mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
add postgres.timeout option to stop unintentionally long queries
This commit is contained in:
parent
29d88513b9
commit
637530a4ce
3 changed files with 71 additions and 5 deletions
1
changelog/61433.added
Normal file
1
changelog/61433.added
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Add postgres.timeout option to postgres module for limiting postgres query times
|
|
@ -16,6 +16,14 @@ Module to provide Postgres compatibility to salt.
|
||||||
This data can also be passed into pillar. Options passed into opts will
|
This data can also be passed into pillar. Options passed into opts will
|
||||||
overwrite options passed into pillar
|
overwrite options passed into pillar
|
||||||
|
|
||||||
|
To prevent Postgres commands from running arbitrarily long, a timeout (in seconds) can be set
|
||||||
|
|
||||||
|
.. code-block:: yaml
|
||||||
|
|
||||||
|
postgres.timeout: 60
|
||||||
|
|
||||||
|
.. versionadded:: 3006.0
|
||||||
|
|
||||||
:note: This module uses MD5 hashing which may not be compliant with certain
|
:note: This module uses MD5 hashing which may not be compliant with certain
|
||||||
security audits.
|
security audits.
|
||||||
|
|
||||||
|
@ -68,7 +76,7 @@ log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
_DEFAULT_PASSWORDS_ENCRYPTION = "md5"
|
_DEFAULT_PASSWORDS_ENCRYPTION = "md5"
|
||||||
_DEFAULT_COMMAND_TIMEOUT_SECS = 60
|
_DEFAULT_COMMAND_TIMEOUT_SECS = 0
|
||||||
_EXTENSION_NOT_INSTALLED = "EXTENSION NOT INSTALLED"
|
_EXTENSION_NOT_INSTALLED = "EXTENSION NOT INSTALLED"
|
||||||
_EXTENSION_INSTALLED = "EXTENSION INSTALLED"
|
_EXTENSION_INSTALLED = "EXTENSION INSTALLED"
|
||||||
_EXTENSION_TO_UPGRADE = "EXTENSION TO UPGRADE"
|
_EXTENSION_TO_UPGRADE = "EXTENSION TO UPGRADE"
|
||||||
|
@ -155,7 +163,9 @@ def _run_psql(cmd, runas=None, password=None, host=None, port=None, user=None):
|
||||||
kwargs = {
|
kwargs = {
|
||||||
"reset_system_locale": False,
|
"reset_system_locale": False,
|
||||||
"clean_env": True,
|
"clean_env": True,
|
||||||
"timeout": _DEFAULT_COMMAND_TIMEOUT_SECS,
|
"timeout": __salt__["config.option"](
|
||||||
|
"postgres.timeout", default=_DEFAULT_COMMAND_TIMEOUT_SECS
|
||||||
|
),
|
||||||
}
|
}
|
||||||
if runas is None:
|
if runas is None:
|
||||||
if not host:
|
if not host:
|
||||||
|
@ -256,7 +266,13 @@ def _run_initdb(
|
||||||
__salt__["file.chown"](pgpassfile, runas, "")
|
__salt__["file.chown"](pgpassfile, runas, "")
|
||||||
cmd.extend(["--pwfile={}".format(pgpassfile)])
|
cmd.extend(["--pwfile={}".format(pgpassfile)])
|
||||||
|
|
||||||
kwargs = dict(runas=runas, clean_env=True, timeout=_DEFAULT_COMMAND_TIMEOUT_SECS)
|
kwargs = dict(
|
||||||
|
runas=runas,
|
||||||
|
clean_env=True,
|
||||||
|
timeout=__salt__["config.option"](
|
||||||
|
"postgres.timeout", default=_DEFAULT_COMMAND_TIMEOUT_SECS
|
||||||
|
),
|
||||||
|
)
|
||||||
cmdstr = " ".join([pipes.quote(c) for c in cmd])
|
cmdstr = " ".join([pipes.quote(c) for c in cmd])
|
||||||
ret = __salt__["cmd.run_all"](cmdstr, python_shell=False, **kwargs)
|
ret = __salt__["cmd.run_all"](cmdstr, python_shell=False, **kwargs)
|
||||||
|
|
||||||
|
@ -1207,7 +1223,7 @@ def _verify_password(role, password, verifier, method):
|
||||||
|
|
||||||
def _md5_password(role, password):
|
def _md5_password(role, password):
|
||||||
return "md5{}".format(
|
return "md5{}".format(
|
||||||
hashlib.md5(
|
hashlib.md5( # nosec
|
||||||
salt.utils.stringutils.to_bytes("{}{}".format(password, role))
|
salt.utils.stringutils.to_bytes("{}{}".format(password, role))
|
||||||
).hexdigest()
|
).hexdigest()
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
import salt.modules.config as configmod
|
||||||
import salt.modules.postgres as postgres
|
import salt.modules.postgres as postgres
|
||||||
from tests.support.mock import MagicMock, patch
|
from tests.support.mock import MagicMock, patch
|
||||||
|
|
||||||
|
@ -28,7 +29,8 @@ def configure_loader_modules():
|
||||||
"file.chown": MagicMock(),
|
"file.chown": MagicMock(),
|
||||||
"file.remove": MagicMock(),
|
"file.remove": MagicMock(),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
configmod: {},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -132,3 +134,50 @@ def test_has_privileges_with_function():
|
||||||
user="testuser",
|
user="testuser",
|
||||||
runas="user",
|
runas="user",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test__runpsql_with_timeout():
|
||||||
|
cmd_run_mock = MagicMock()
|
||||||
|
postgres_opts = {
|
||||||
|
"config.option": configmod.option,
|
||||||
|
"cmd.run_all": cmd_run_mock,
|
||||||
|
}
|
||||||
|
kwargs = {
|
||||||
|
"reset_system_locale": False,
|
||||||
|
"clean_env": True,
|
||||||
|
"runas": "saltuser",
|
||||||
|
"python_shell": False,
|
||||||
|
}
|
||||||
|
with patch.dict(postgres.__salt__, postgres_opts):
|
||||||
|
with patch.dict(
|
||||||
|
configmod.__opts__, {"postgres.timeout": 60, "postgres.pass": None}
|
||||||
|
):
|
||||||
|
postgres._run_psql("fakecmd", runas="saltuser")
|
||||||
|
cmd_run_mock.assert_called_with("fakecmd", timeout=60, **kwargs)
|
||||||
|
with patch.dict(configmod.__opts__, {"postgres.pass": None}):
|
||||||
|
postgres._run_psql("fakecmd", runas="saltuser")
|
||||||
|
cmd_run_mock.assert_called_with("fakecmd", timeout=0, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def test__run_initdb_with_timeout():
|
||||||
|
cmd_run_mock = MagicMock(return_value={})
|
||||||
|
postgres_opts = {
|
||||||
|
"config.option": configmod.option,
|
||||||
|
"cmd.run_all": cmd_run_mock,
|
||||||
|
}
|
||||||
|
kwargs = {
|
||||||
|
"clean_env": True,
|
||||||
|
"runas": "saltuser",
|
||||||
|
"python_shell": False,
|
||||||
|
}
|
||||||
|
cmd_str = "/fake/path --pgdata=fakename --username=saltuser --auth=password --encoding=UTF8"
|
||||||
|
with patch.dict(postgres.__salt__, postgres_opts):
|
||||||
|
with patch.object(postgres, "_find_pg_binary", return_value="/fake/path"):
|
||||||
|
with patch.dict(
|
||||||
|
configmod.__opts__, {"postgres.timeout": 60, "postgres.pass": None}
|
||||||
|
):
|
||||||
|
postgres._run_initdb("fakename", runas="saltuser")
|
||||||
|
cmd_run_mock.assert_called_with(cmd_str, timeout=60, **kwargs)
|
||||||
|
with patch.dict(configmod.__opts__, {"postgres.pass": None}):
|
||||||
|
postgres._run_initdb("fakename", runas="saltuser")
|
||||||
|
cmd_run_mock.assert_called_with(cmd_str, timeout=0, **kwargs)
|
||||||
|
|
Loading…
Add table
Reference in a new issue