summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2020-05-19 22:32:22 +0200
committerGitHub <noreply@github.com>2020-05-19 22:32:22 +0200
commitb708a375010c7240d11412d92f8552dbba2abdc0 (patch)
tree01428d83fe5375545afee1f6359d35e0ab7ad2ba
parentb645e28edb6e92fe13e781c0d29853aebaceb711 (diff)
parent43dd945c5a45c86c491892f30546d0179751bf4a (diff)
downloadvyos-1x-b708a375010c7240d11412d92f8552dbba2abdc0.tar.gz
vyos-1x-b708a375010c7240d11412d92f8552dbba2abdc0.zip
Merge pull request #414 from thomas-mangin/T2467
util: T2467: automatically add sudo to known commands
-rw-r--r--python/vyos/util.py50
-rwxr-xr-xsrc/conf_mode/http-api.py4
-rwxr-xr-xsrc/conf_mode/https.py4
-rwxr-xr-xsrc/conf_mode/igmp_proxy.py2
-rwxr-xr-xsrc/conf_mode/lldp.py4
-rwxr-xr-xsrc/conf_mode/ntp.py4
-rwxr-xr-xsrc/conf_mode/ssh.py4
-rwxr-xr-xsrc/conf_mode/vrrp.py6
-rwxr-xr-xsrc/op_mode/flow_accounting_op.py2
9 files changed, 51 insertions, 29 deletions
diff --git a/python/vyos/util.py b/python/vyos/util.py
index 381cd0358..c2479aac4 100644
--- a/python/vyos/util.py
+++ b/python/vyos/util.py
@@ -21,12 +21,24 @@ import sys
# 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 _need_sudo(command):
+ return os.path.basename(command.split()[0]) in ('systemctl', )
+
+
+def _add_sudo(command):
+ if _need_sudo(command):
+ return 'sudo ' + command
+ return command
+
+
+from subprocess import Popen
+from subprocess import PIPE
+from subprocess import DEVNULL
+
+
def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=PIPE, stderr=PIPE, decode='utf-8'):
+ stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True):
"""
popen is a wrapper helper aound subprocess.Popen
with it default setting it will return a tuple (out, err)
@@ -52,15 +64,22 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
the default is explicitely utf-8 which is python's own default
usage:
- to get both stdout, and stderr: popen('command', stdout=PIPE, stderr=STDOUT)
- to discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE)
+ get both stdout and stderr: popen('command', stdout=PIPE, stderr=STDOUT)
+ discard stdout and get stderr: popen('command', stdout=DEVNUL, stderr=PIPE)
"""
+
+ # airbag must be left as an import in the function as otherwise we have a
+ # a circual import dependency
from vyos import debug
from vyos import airbag
+
# log if the flag is set, otherwise log if command is set
if not debug.enabled(flag):
flag = 'command'
+ if autosudo:
+ command = _add_sudo(command)
+
cmd_msg = f"cmd '{command}'"
debug.message(cmd_msg, flag)
@@ -72,9 +91,11 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
use_shell = True
if env:
use_shell = True
+
if input:
stdin = PIPE
input = input.encode() if type(input) is str else input
+
p = Popen(
command,
stdin=stdin, stdout=stdout, stderr=stderr,
@@ -112,9 +133,9 @@ def popen(command, flag='', shell=None, input=None, timeout=None, env=None,
def run(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=DEVNULL, stderr=PIPE, decode='utf-8'):
+ stdout=DEVNULL, stderr=PIPE, decode='utf-8', autosudo=True):
"""
- A wrapper around vyos.util.popen, which discard the stdout and
+ A wrapper around popen, which discard the stdout and
will return the error code of a command
"""
_, code = popen(
@@ -128,14 +149,15 @@ def run(command, flag='', shell=None, input=None, timeout=None, env=None,
def cmd(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=PIPE, stderr=PIPE, decode='utf-8',
+ stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True,
raising=None, message='', expect=[0]):
"""
- A wrapper around vyos.util.popen, which returns the stdout and
+ A wrapper around popen, which returns the stdout and
will raise the error code of a command
- raising: specify which call should be used when raising (default is OSError)
+ raising: specify which call should be used when raising
the class should only require a string as parameter
+ (default is OSError) with the error code
expect: a list of error codes to consider as normal
"""
decoded, code = popen(
@@ -159,9 +181,9 @@ def cmd(command, flag='', shell=None, input=None, timeout=None, env=None,
def call(command, flag='', shell=None, input=None, timeout=None, env=None,
- stdout=PIPE, stderr=PIPE, decode='utf-8'):
+ stdout=PIPE, stderr=PIPE, decode='utf-8', autosudo=True):
"""
- A wrapper around vyos.util.popen, which print the stdout and
+ A wrapper around popen, which print the stdout and
will return the error code of a command
"""
out, code = popen(
diff --git a/src/conf_mode/http-api.py b/src/conf_mode/http-api.py
index 26f4aea7f..3b8a67ef6 100755
--- a/src/conf_mode/http-api.py
+++ b/src/conf_mode/http-api.py
@@ -92,9 +92,9 @@ def generate(http_api):
def apply(http_api):
if http_api is not None:
- call('sudo systemctl restart vyos-http-api.service')
+ call('systemctl restart vyos-http-api.service')
else:
- call('sudo systemctl stop vyos-http-api.service')
+ call('systemctl stop vyos-http-api.service')
for dep in dependencies:
cmd(f'{vyos_conf_scripts_dir}/{dep}', raising=ConfigError)
diff --git a/src/conf_mode/https.py b/src/conf_mode/https.py
index 7d3a1b9cb..718e8375c 100755
--- a/src/conf_mode/https.py
+++ b/src/conf_mode/https.py
@@ -141,9 +141,9 @@ def generate(https):
def apply(https):
if https is not None:
- call('sudo systemctl restart nginx.service')
+ call('systemctl restart nginx.service')
else:
- call('sudo systemctl stop nginx.service')
+ call('systemctl stop nginx.service')
if __name__ == '__main__':
try:
diff --git a/src/conf_mode/igmp_proxy.py b/src/conf_mode/igmp_proxy.py
index 9fa591a2c..9cd7163f0 100755
--- a/src/conf_mode/igmp_proxy.py
+++ b/src/conf_mode/igmp_proxy.py
@@ -121,7 +121,7 @@ def generate(igmp_proxy):
def apply(igmp_proxy):
if igmp_proxy is None or igmp_proxy['disable']:
# IGMP Proxy support is removed in the commit
- call('sudo systemctl stop igmpproxy.service')
+ call('systemctl stop igmpproxy.service')
if os.path.exists(config_file):
os.unlink(config_file)
else:
diff --git a/src/conf_mode/lldp.py b/src/conf_mode/lldp.py
index d128c1fe6..6446074d8 100755
--- a/src/conf_mode/lldp.py
+++ b/src/conf_mode/lldp.py
@@ -228,10 +228,10 @@ def generate(lldp):
def apply(lldp):
if lldp:
# start/restart lldp service
- call('sudo systemctl restart lldpd.service')
+ call('systemctl restart lldpd.service')
else:
# LLDP service has been terminated
- call('sudo systemctl stop lldpd.service')
+ call('systemctl stop lldpd.service')
os.unlink(config_file)
os.unlink(vyos_config_file)
diff --git a/src/conf_mode/ntp.py b/src/conf_mode/ntp.py
index 6d32f7fd6..85f60293d 100755
--- a/src/conf_mode/ntp.py
+++ b/src/conf_mode/ntp.py
@@ -103,10 +103,10 @@ def generate(ntp):
def apply(ntp):
if ntp is not None:
- call('sudo systemctl restart ntp.service')
+ call('systemctl restart ntp.service')
else:
# NTP support is removed in the commit
- call('sudo systemctl stop ntp.service')
+ call('systemctl stop ntp.service')
os.unlink(config_file)
return None
diff --git a/src/conf_mode/ssh.py b/src/conf_mode/ssh.py
index ae79eac2d..76fdad8ae 100755
--- a/src/conf_mode/ssh.py
+++ b/src/conf_mode/ssh.py
@@ -124,10 +124,10 @@ def generate(ssh):
def apply(ssh):
if ssh is not None and 'port' in ssh.keys():
- call("sudo systemctl restart ssh.service")
+ call("systemctl restart ssh.service")
else:
# SSH access is removed in the commit
- call("sudo systemctl stop ssh.service")
+ call("systemctl stop ssh.service")
if os.path.isfile(config_file):
os.unlink(config_file)
diff --git a/src/conf_mode/vrrp.py b/src/conf_mode/vrrp.py
index f358891a5..1a5ad1f8c 100755
--- a/src/conf_mode/vrrp.py
+++ b/src/conf_mode/vrrp.py
@@ -227,17 +227,17 @@ def apply(data):
if not VRRP.is_running():
print("Starting the VRRP process")
- ret = call("sudo systemctl restart keepalived.service")
+ ret = call("systemctl restart keepalived.service")
else:
print("Reloading the VRRP process")
- ret = call("sudo systemctl reload keepalived.service")
+ ret = call("systemctl reload keepalived.service")
if ret != 0:
raise ConfigError("keepalived failed to start")
else:
# VRRP is removed in the commit
print("Stopping the VRRP process")
- call("sudo systemctl stop keepalived.service")
+ call("systemctl stop keepalived.service")
os.unlink(VRRP.location['daemon'])
return None
diff --git a/src/op_mode/flow_accounting_op.py b/src/op_mode/flow_accounting_op.py
index 219ad6316..bf8c39fd6 100755
--- a/src/op_mode/flow_accounting_op.py
+++ b/src/op_mode/flow_accounting_op.py
@@ -195,7 +195,7 @@ if not _uacctd_running():
# restart pmacct daemon
if cmd_args.action == 'restart':
# run command to restart flow-accounting
- cmd('sudo systemctl restart uacctd.service',
+ cmd('systemctl restart uacctd.service',
message='Failed to restart flow-accounting')
# clear in-memory collected flows