aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake Hunsaker <jhunsake@redhat.com>2020-01-28 17:54:59 +0100
committerPavel Moravec <pmoravec@redhat.com>2020-01-28 17:56:21 +0100
commit9d1e5a0f7b757fa1c82aee7578ad4f7ab8080c5e (patch)
treee8dc594e3218d70c0001d4a92aab9a59a1b8b3f0
parentf41e8f22143391a4e38282e60fc8390713c3be10 (diff)
parent645b9c98dc8f509839e37055050be4f39d6161d2 (diff)
downloadsos-9d1e5a0f7b757fa1c82aee7578ad4f7ab8080c5e.tar.gz
[Plugin] Allow selectively disabling postprocessing
Adds two mechanisms by which users can choose to disable postprocessing of collected information. First, is a global method exposed via the `--no-postproc` option. Using this option will skip postprocessing for all plugins. Second, is a per-plugin option exposed via a new 'postproc' plugin option. This is set to _True_ by default (meaning yes, perform postprocessing), which users can set to False or off to disable postprocessing for that plugin only; e.g. `-k podman.postproc=off` Closes: #286 Resolves: #1862 Signed-off-by: Jake Hunsaker <jhunsake@redhat.com> Signed-off-by: Pavel Moravec <pmoravec@redhat.com>
-rw-r--r--man/en/sosreport.111
-rw-r--r--sos/__init__.py6
-rw-r--r--sos/plugins/__init__.py10
-rw-r--r--sos/sosreport.py25
-rw-r--r--tests/plugin_tests.py22
5 files changed, 63 insertions, 11 deletions
diff --git a/man/en/sosreport.1 b/man/en/sosreport.1
index 75819b6e..5a39dc64 100644
--- a/man/en/sosreport.1
+++ b/man/en/sosreport.1
@@ -10,6 +10,7 @@ sosreport \- Collect and package diagnostic and support data
[-a|--alloptions] [-v|--verbose]\fR
[-k plug.opt|--plugin-option plug.opt]\fR
[--no-report] [--config-file conf]\fR
+ [--no-postproc]\fR
[--preset preset] [--add-preset add_preset]\fR
[--del-preset del_preset] [--desc description]\fR
[--batch] [--build] [--debug] [--dry-run]\fR
@@ -82,6 +83,16 @@ Disable HTML report writing.
.B \--config-file CONFIG
Specify alternate configuration file.
.TP
+.B \-\-no-postproc
+Disable postprocessing globally for all plugins. This will mean data is not
+obfuscated/sanitized from the archive during collection.
+
+Note that this means data such as password, SSH keys, certificates, etc...
+will be collected in plain text.
+
+To selectively disable postprocessing on a per-plugin basis, use the 'postproc'
+plugin option available to all plugins, e.g. '-k podman.postproc=off'.
+.TP
.B \--preset PRESET
Specify an existing preset to use for sos options.
diff --git a/sos/__init__.py b/sos/__init__.py
index a01b6b9f..c9f20e59 100644
--- a/sos/__init__.py
+++ b/sos/__init__.py
@@ -55,8 +55,9 @@ _arg_names = [
'debug', 'del_preset', 'dry_run', 'enableplugins', 'encrypt_key',
'encrypt_pass', 'experimental', 'label', 'list_plugins', 'list_presets',
'list_profiles', 'log_size', 'noplugins', 'noreport', 'no_env_vars',
- 'note', 'onlyplugins', 'plugin_timeout', 'plugopts', 'preset', 'profiles',
- 'quiet', 'since', 'sysroot', 'threads', 'tmp_dir', 'verbosity', 'verify'
+ 'no_postproc', 'note', 'onlyplugins', 'plugin_timeout', 'plugopts',
+ 'preset', 'profiles', 'quiet', 'since', 'sysroot', 'threads', 'tmp_dir',
+ 'verbosity', 'verify'
]
#: Arguments with non-zero default values
@@ -182,6 +183,7 @@ class SoSOptions(object):
self.noreport = False
self.allow_system_changes = False
self.no_env_vars = False
+ self.no_postproc = False
self.note = ""
self.onlyplugins = []
self.plugin_timeout = None
diff --git a/sos/plugins/__init__.py b/sos/plugins/__init__.py
index eb65cb63..22d366a4 100644
--- a/sos/plugins/__init__.py
+++ b/sos/plugins/__init__.py
@@ -368,6 +368,11 @@ class Plugin(object):
# Default predicates
predicate = None
cmd_predicate = None
+ _default_plug_opts = [
+ ('timeout', 'Timeout in seconds for plugin', 'fast', -1),
+ ('postproc', 'Enable post-processing collected plugin data', 'fast',
+ True)
+ ]
def __init__(self, commons):
if not getattr(self, "option_list", False):
@@ -391,9 +396,8 @@ class Plugin(object):
self.soslog = self.commons['soslog'] if 'soslog' in self.commons \
else logging.getLogger('sos')
- # add the 'timeout' plugin option automatically
- self.option_list.append(('timeout', 'timeout in seconds for plugin',
- 'fast', -1))
+ # add the default plugin opts
+ self.option_list.extend(self._default_plug_opts)
# get the option list into a dictionary
for opt in self.option_list:
diff --git a/sos/sosreport.py b/sos/sosreport.py
index c41bdc64..2d2d1599 100644
--- a/sos/sosreport.py
+++ b/sos/sosreport.py
@@ -199,6 +199,9 @@ def _get_parser():
parser.add_argument("--no-env-vars", action="store_true", default=False,
dest="no_env_vars",
help="Do not collect environment variables")
+ parser.add_argument("--no-postproc", default=False, dest="no_postproc",
+ action="store_true",
+ help="Disable all post-processing")
parser.add_argument("--note", type=str, action="store", default="",
help="Behaviour notes for new preset")
parser.add_argument("-o", "--only-plugins", action="extend",
@@ -754,12 +757,15 @@ class SoSReport(object):
self.ui_log.info("")
if self.all_options:
+ self.ui_log.info(_("The following options are available for ALL "
+ "plugins:"))
+ for opt in self.all_options[0][0]._default_plug_opts:
+ self.ui_log.info(" %-25s %-15s %s" % (opt[0], opt[3], opt[1]))
+ self.ui_log.info("")
+
self.ui_log.info(_("The following plugin options are available:"))
- self.ui_log.info(_("\n Option 'timeout' available to all plugins -"
- " time in seconds to allow plugin to run, use 0"
- " for no timeout\n"))
for (plug, plugname, optname, optparm) in self.all_options:
- if optname == 'timeout':
+ if optname in ('timeout', 'postproc'):
continue
# format option value based on its type (int or bool)
if type(optparm["enabled"]) == bool:
@@ -1163,7 +1169,11 @@ class SoSReport(object):
def postproc(self):
for plugname, plug in self.loaded_plugins:
try:
- plug.postproc()
+ if plug.get_option('postproc'):
+ plug.postproc()
+ else:
+ self.soslog.info("Skipping postproc for plugin %s"
+ % plugname)
except (OSError, IOError) as e:
if e.errno in fatal_fs_errors:
self.ui_log.error("")
@@ -1361,7 +1371,10 @@ class SoSReport(object):
self.collect_env_vars()
if not self.opts.noreport:
self.generate_reports()
- self.postproc()
+ if not self.opts.no_postproc:
+ self.postproc()
+ else:
+ self.ui_log.info("Skipping postprocessing of collected data")
self.version()
return self.final_work()
diff --git a/tests/plugin_tests.py b/tests/plugin_tests.py
index 6522fe14..9f03afa2 100644
--- a/tests/plugin_tests.py
+++ b/tests/plugin_tests.py
@@ -75,6 +75,18 @@ class NamedMockPlugin(Plugin):
pass
+class PostprocMockPlugin(Plugin):
+
+ did_postproc = False
+
+ def setup(self):
+ pass
+
+ def postproc(self):
+ if self.get_option('postproc'):
+ self.did_postproc = True
+
+
class ForbiddenMockPlugin(Plugin):
"""This plugin has a description."""
@@ -97,6 +109,7 @@ class MockOptions(object):
since = None
log_size = 25
allow_system_changes = False
+ no_postproc = False
class PluginToolTests(unittest.TestCase):
@@ -239,6 +252,15 @@ class PluginTests(unittest.TestCase):
p.collect()
self.assertEquals(p.archive.m, {})
+ def test_postproc_default_on(self):
+ p = PostprocMockPlugin({
+ 'cmdlineopts': MockOptions(),
+ 'sysroot': self.sysroot,
+ 'policy': LinuxPolicy()
+ })
+ p.postproc()
+ self.assertTrue(p.did_postproc)
+
class AddCopySpecTests(unittest.TestCase):