Additional fixes for using cron state with non-root Minion (#56973)

* Fixed cron state to make it work with non-root minions

* Added changelogs

Co-authored-by: Daniel Wozniak <dwozniak@saltstack.com>
This commit is contained in:
Proskurin Kirill 2020-04-29 23:14:47 +01:00 committed by GitHub
parent 43bd67609b
commit 60f1303471
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 112 additions and 2 deletions

View file

@ -16,6 +16,7 @@ Versions are `MAJOR.PATCH`.
### Changed
### Fixed
- [#51872](https://github.com/saltstack/salt/issues/51872) - Additional fixes for using cron state with non-root Minion - [@Oloremo](https://github.com/Oloremo)
- [#40491](https://github.com/saltstack/salt/issues/40491) - Fixed trim_output logic in archive.extracted state - [@Oloremo](https://github.com/Oloremo)
### Added

1
changelog/51872.fixed Normal file
View file

@ -0,0 +1 @@
Additional fixes for using cron state with non-root Minion

View file

@ -288,7 +288,7 @@ def _write_cron_lines(user, lines):
else:
with salt.utils.files.fpopen(path, "w+", mode=0o600) as fp_:
fp_.writelines(lines)
ret = __salt__["cmd.run_all"](_get_cron_cmdstr(path, user), python_shell=False)
ret = __salt__["cmd.run_all"](_get_cron_cmdstr(path), python_shell=False)
os.remove(path)
return ret

View file

@ -12,7 +12,7 @@ from salt.ext.six.moves import StringIO, builtins, range
# Import Salt Testing libs
from tests.support.mixins import LoaderModuleMockMixin
from tests.support.mock import MagicMock, call, patch
from tests.support.mock import MagicMock, call, mock_open, patch
from tests.support.unit import TestCase
STUB_USER = "root"
@ -1398,3 +1398,111 @@ class PsTestCase(TestCase, LoaderModuleMockMixin):
):
ret = cron.rm_job("DUMMY_USER", "/bin/echo NOT A DROID", 1, 2, 3, 4, 5)
self.assertEqual("absent", ret)
def test_write_cron_lines_root_rh(self):
"""
Assert that _write_cron_lines() is called with the correct cron command and user
OS: RedHat. User: root. Expected to run with runas argument.
"""
temp_path = "some_temp_path"
crontab_cmd = "crontab {}".format(temp_path)
with patch.dict(cron.__grains__, {"os_family": "RedHat"}), patch.dict(
cron.__salt__, {"cmd.run_all": MagicMock()}
), patch(
"salt.modules.cron._check_instance_uid_match",
new=MagicMock(return_value=True),
), patch(
"salt.utils.files.fpopen", mock_open()
), patch.dict(
cron.__salt__, {"file.user_to_uid": MagicMock(return_value=1)}
), patch(
"salt.utils.files.mkstemp", MagicMock(return_value=temp_path)
), patch(
"os.remove", MagicMock()
):
cron._write_cron_lines("root", "test 123")
cron.__salt__["cmd.run_all"].assert_called_with(
crontab_cmd, python_shell=False, runas="root"
)
def test_write_cron_lines_non_root_rh(self):
"""
Assert that _write_cron_lines() is called with the correct cron command and user
OS: RedHat. User: non-root. Expected to run without runas argument.
"""
temp_path = "some_temp_path"
crontab_cmd = "crontab {}".format(temp_path)
with patch.dict(cron.__grains__, {"os_family": "RedHat"}), patch.dict(
cron.__salt__, {"cmd.run_all": MagicMock()}
), patch(
"salt.modules.cron._check_instance_uid_match",
new=MagicMock(return_value=False),
), patch(
"salt.utils.files.fpopen", mock_open()
), patch.dict(
cron.__salt__, {"file.user_to_uid": MagicMock(return_value=1)}
), patch(
"salt.utils.files.mkstemp", MagicMock(return_value=temp_path)
), patch(
"os.remove", MagicMock()
):
cron._write_cron_lines("non-root", "test 123")
cron.__salt__["cmd.run_all"].assert_called_with(
crontab_cmd, python_shell=False
)
def test_write_cron_lines_non_root_aix(self):
"""
Assert that _write_cron_lines() is called with the correct cron command and user
OS: AIX. User: non-root. Expected to run with runas argument.
"""
temp_path = "some_temp_path"
crontab_cmd = "crontab {}".format(temp_path)
with patch.dict(cron.__grains__, {"os_family": "AIX"}), patch.dict(
cron.__salt__, {"cmd.run_all": MagicMock()}
), patch(
"salt.modules.cron._check_instance_uid_match",
new=MagicMock(return_value=False),
), patch(
"salt.utils.files.fpopen", mock_open()
), patch.dict(
cron.__salt__, {"file.user_to_uid": MagicMock(return_value=1)}
), patch(
"salt.utils.files.mkstemp", MagicMock(return_value=temp_path)
), patch(
"os.remove", MagicMock()
):
cron._write_cron_lines("non-root", "test 123")
cron.__salt__["cmd.run_all"].assert_called_with(
crontab_cmd, python_shell=False, runas="non-root"
)
def test_write_cron_lines_non_root_solaris(self):
"""
Assert that _write_cron_lines() is called with the correct cron command and user
OS: Solaris. User: non-root. Expected to run with runas argument.
"""
temp_path = "some_temp_path"
crontab_cmd = "crontab {}".format(temp_path)
with patch.dict(cron.__grains__, {"os_family": "AIX"}), patch.dict(
cron.__salt__, {"cmd.run_all": MagicMock()}
), patch(
"salt.modules.cron._check_instance_uid_match",
new=MagicMock(return_value=False),
), patch(
"salt.utils.files.fpopen", mock_open()
), patch.dict(
cron.__salt__, {"file.user_to_uid": MagicMock(return_value=1)}
), patch(
"salt.utils.files.mkstemp", MagicMock(return_value=temp_path)
), patch(
"os.remove", MagicMock()
):
cron._write_cron_lines("non-root", "test 123")
cron.__salt__["cmd.run_all"].assert_called_with(
crontab_cmd, python_shell=False, runas="non-root"
)