mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Fix an issue with the openscap module
Fixes an issue with the openscap module where it would fail if the command returned an exit code not found in the exit_codes_map dictionary. Instead of failing, let's return false with the exit code and error message in the return.
This commit is contained in:
parent
bd52be3a70
commit
d16815dab5
2 changed files with 212 additions and 1 deletions
|
@ -92,8 +92,8 @@ def xccdf(params):
|
|||
tempdir = tempfile.mkdtemp()
|
||||
proc = Popen(shlex.split(cmd), stdout=PIPE, stderr=PIPE, cwd=tempdir)
|
||||
(stdoutdata, error) = proc.communicate()
|
||||
success = _OSCAP_EXIT_CODES_MAP[proc.returncode]
|
||||
returncode = proc.returncode
|
||||
success = _OSCAP_EXIT_CODES_MAP.get(returncode, False)
|
||||
if success:
|
||||
__salt__["cp.push_dir"](tempdir)
|
||||
shutil.rmtree(tempdir, ignore_errors=True)
|
||||
|
|
211
tests/pytests/unit/modules/test_openscap.py
Normal file
211
tests/pytests/unit/modules/test_openscap.py
Normal file
|
@ -0,0 +1,211 @@
|
|||
import subprocess
|
||||
|
||||
import pytest
|
||||
|
||||
import salt.modules.openscap as openscap
|
||||
from tests.support.mock import MagicMock, Mock, patch
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def policy_file():
|
||||
yield "/usr/share/openscap/policy-file-xccdf.xml"
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def configure_loader_modules(tmp_path):
|
||||
return {
|
||||
openscap: {
|
||||
"__salt__": MagicMock(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_success(policy_file, tmp_path):
|
||||
patch_rmtree = patch("shutil.rmtree", Mock())
|
||||
mock_mkdtemp = Mock(return_value=str(tmp_path))
|
||||
patch_mkdtemp = patch("tempfile.mkdtemp", mock_mkdtemp)
|
||||
mock_popen = MagicMock(
|
||||
return_value=Mock(**{"returncode": 0, "communicate.return_value": ("", "")})
|
||||
)
|
||||
patch_popen = patch.object(openscap, "Popen", mock_popen)
|
||||
with patch_popen, patch_rmtree, patch_mkdtemp:
|
||||
response = openscap.xccdf("eval --profile Default {}".format(policy_file))
|
||||
|
||||
assert mock_mkdtemp.call_count == 1
|
||||
expected_cmd = [
|
||||
"oscap",
|
||||
"xccdf",
|
||||
"eval",
|
||||
"--oval-results",
|
||||
"--results",
|
||||
"results.xml",
|
||||
"--report",
|
||||
"report.html",
|
||||
"--profile",
|
||||
"Default",
|
||||
policy_file,
|
||||
]
|
||||
openscap.Popen.assert_called_once_with(
|
||||
expected_cmd,
|
||||
cwd=openscap.tempfile.mkdtemp.return_value,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
openscap.__salt__["cp.push_dir"].assert_called_once_with(str(tmp_path))
|
||||
assert openscap.shutil.rmtree.call_count == 1
|
||||
expected = {
|
||||
"upload_dir": str(tmp_path),
|
||||
"error": "",
|
||||
"success": True,
|
||||
"returncode": 0,
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_success_with_failing_rules(policy_file, tmp_path):
|
||||
patch_rmtree = patch("shutil.rmtree", Mock())
|
||||
mock_mkdtemp = Mock(return_value=str(tmp_path))
|
||||
patch_mkdtemp = patch("tempfile.mkdtemp", mock_mkdtemp)
|
||||
mock_popen = MagicMock(
|
||||
return_value=Mock(
|
||||
**{"returncode": 2, "communicate.return_value": ("", "some error")}
|
||||
)
|
||||
)
|
||||
patch_popen = patch.object(openscap, "Popen", mock_popen)
|
||||
with patch_popen, patch_mkdtemp, patch_rmtree as mock_rmtree:
|
||||
response = openscap.xccdf("eval --profile Default {}".format(policy_file))
|
||||
|
||||
assert mock_mkdtemp.call_count == 1
|
||||
expected_cmd = [
|
||||
"oscap",
|
||||
"xccdf",
|
||||
"eval",
|
||||
"--oval-results",
|
||||
"--results",
|
||||
"results.xml",
|
||||
"--report",
|
||||
"report.html",
|
||||
"--profile",
|
||||
"Default",
|
||||
policy_file,
|
||||
]
|
||||
openscap.Popen.assert_called_once_with(
|
||||
expected_cmd,
|
||||
cwd=openscap.tempfile.mkdtemp.return_value,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
openscap.__salt__["cp.push_dir"].assert_called_once_with(str(tmp_path))
|
||||
assert mock_rmtree.call_count == 1
|
||||
expected = {
|
||||
"upload_dir": str(tmp_path),
|
||||
"error": "some error",
|
||||
"success": True,
|
||||
"returncode": 2,
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_fail_no_profile():
|
||||
response = openscap.xccdf("eval --param Default /unknown/param")
|
||||
error = "the following arguments are required: --profile"
|
||||
expected = {
|
||||
"error": error,
|
||||
"upload_dir": None,
|
||||
"success": False,
|
||||
"returncode": None,
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_success_ignore_unknown_params(tmp_path):
|
||||
mock_mkdtemp = Mock(return_value=str(tmp_path))
|
||||
patch_mkdtemp = patch("tempfile.mkdtemp", mock_mkdtemp)
|
||||
mock_popen = MagicMock(
|
||||
return_value=Mock(
|
||||
**{"returncode": 2, "communicate.return_value": ("", "some error")}
|
||||
)
|
||||
)
|
||||
patch_popen = patch("salt.modules.openscap.Popen", mock_popen)
|
||||
with patch_popen, patch_mkdtemp:
|
||||
response = openscap.xccdf("eval --profile Default --param Default /policy/file")
|
||||
expected = {
|
||||
"upload_dir": str(tmp_path),
|
||||
"error": "some error",
|
||||
"success": True,
|
||||
"returncode": 2,
|
||||
}
|
||||
assert response == expected
|
||||
expected_cmd = [
|
||||
"oscap",
|
||||
"xccdf",
|
||||
"eval",
|
||||
"--oval-results",
|
||||
"--results",
|
||||
"results.xml",
|
||||
"--report",
|
||||
"report.html",
|
||||
"--profile",
|
||||
"Default",
|
||||
"/policy/file",
|
||||
]
|
||||
openscap.Popen.assert_called_once_with(
|
||||
expected_cmd,
|
||||
cwd=openscap.tempfile.mkdtemp.return_value,
|
||||
stderr=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_evaluation_error(policy_file):
|
||||
mock_popen = MagicMock(
|
||||
return_value=Mock(
|
||||
**{
|
||||
"returncode": 1,
|
||||
"communicate.return_value": ("", "evaluation error"),
|
||||
}
|
||||
)
|
||||
)
|
||||
patch_popen = patch("salt.modules.openscap.Popen", mock_popen)
|
||||
with patch_popen:
|
||||
response = openscap.xccdf("eval --profile Default {}".format(policy_file))
|
||||
expected = {
|
||||
"upload_dir": None,
|
||||
"error": "evaluation error",
|
||||
"success": False,
|
||||
"returncode": 1,
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_fail_not_implemented_action(policy_file):
|
||||
response = openscap.xccdf("info {}".format(policy_file))
|
||||
mock_err = "argument action: invalid choice: 'info' (choose from 'eval')"
|
||||
expected = {
|
||||
"upload_dir": None,
|
||||
"error": mock_err,
|
||||
"success": False,
|
||||
"returncode": None,
|
||||
}
|
||||
assert response == expected
|
||||
|
||||
|
||||
def test_openscap_xccdf_eval_evaluation_unknown_error(policy_file):
|
||||
mock_popen = MagicMock(
|
||||
return_value=Mock(
|
||||
**{
|
||||
"returncode": 255,
|
||||
"communicate.return_value": ("", "unknown error"),
|
||||
}
|
||||
)
|
||||
)
|
||||
patch_popen = patch("salt.modules.openscap.Popen", mock_popen)
|
||||
with patch_popen:
|
||||
response = openscap.xccdf("eval --profile Default {}".format(policy_file))
|
||||
expected = {
|
||||
"upload_dir": None,
|
||||
"error": "unknown error",
|
||||
"success": False,
|
||||
"returncode": 255,
|
||||
}
|
||||
assert response == expected
|
Loading…
Add table
Reference in a new issue