65598582f5
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=179
514 lines
20 KiB
Diff
514 lines
20 KiB
Diff
From 2ae9fa97c88889a1a99f0ccd43aea0fe996aad7a Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?=
|
|
<psuarezhernandez@suse.com>
|
|
Date: Wed, 1 Apr 2020 12:27:30 +0100
|
|
Subject: [PATCH] Sanitize grains loaded from roster_grains.json
|
|
|
|
Ensure _format_cached_grains is called on state.pkg test
|
|
---
|
|
salt/modules/state.py | 76 +++++++++++++++-----------------
|
|
tests/unit/modules/test_state.py | 57 ++++++++++--------------
|
|
2 files changed, 59 insertions(+), 74 deletions(-)
|
|
|
|
diff --git a/salt/modules/state.py b/salt/modules/state.py
|
|
index 1c864f7504..b439f79e57 100644
|
|
--- a/salt/modules/state.py
|
|
+++ b/salt/modules/state.py
|
|
@@ -1,4 +1,3 @@
|
|
-# -*- coding: utf-8 -*-
|
|
"""
|
|
Control the state system on the minion.
|
|
|
|
@@ -11,8 +10,6 @@ highdata and won't hit the fileserver except for ``salt://`` links in the
|
|
states themselves.
|
|
"""
|
|
|
|
-# Import python libs
|
|
-from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import logging
|
|
import os
|
|
@@ -22,7 +19,6 @@ import tarfile
|
|
import tempfile
|
|
import time
|
|
|
|
-# Import salt libs
|
|
import salt.config
|
|
import salt.defaults.exitcodes
|
|
import salt.payload
|
|
@@ -42,8 +38,6 @@ import salt.utils.stringutils
|
|
import salt.utils.url
|
|
import salt.utils.versions
|
|
from salt.exceptions import CommandExecutionError, SaltInvocationError
|
|
-
|
|
-# Import 3rd-party libs
|
|
from salt.ext import six
|
|
from salt.loader import _format_cached_grains
|
|
from salt.runners.state import orchestrate as _orchestrate
|
|
@@ -89,11 +83,11 @@ def _filter_running(runnings):
|
|
"""
|
|
Filter out the result: True + no changes data
|
|
"""
|
|
- ret = dict(
|
|
- (tag, value)
|
|
- for tag, value in six.iteritems(runnings)
|
|
+ ret = {
|
|
+ tag: value
|
|
+ for tag, value in runnings.items()
|
|
if not value["result"] or value["changes"]
|
|
- )
|
|
+ }
|
|
return ret
|
|
|
|
|
|
@@ -151,7 +145,7 @@ def _snapper_pre(opts, jid):
|
|
snapper_pre = __salt__["snapper.create_snapshot"](
|
|
config=__opts__.get("snapper_states_config", "root"),
|
|
snapshot_type="pre",
|
|
- description="Salt State run for jid {0}".format(jid),
|
|
+ description="Salt State run for jid {}".format(jid),
|
|
__pub_jid=jid,
|
|
)
|
|
except Exception: # pylint: disable=broad-except
|
|
@@ -170,7 +164,7 @@ def _snapper_post(opts, jid, pre_num):
|
|
config=__opts__.get("snapper_states_config", "root"),
|
|
snapshot_type="post",
|
|
pre_number=pre_num,
|
|
- description="Salt State run for jid {0}".format(jid),
|
|
+ description="Salt State run for jid {}".format(jid),
|
|
__pub_jid=jid,
|
|
)
|
|
except Exception: # pylint: disable=broad-except
|
|
@@ -216,7 +210,7 @@ def get_pauses(jid=None):
|
|
elif isinstance(jid, list):
|
|
jids = salt.utils.data.stringify(jid)
|
|
else:
|
|
- jids = [six.text_type(jid)]
|
|
+ jids = [str(jid)]
|
|
for scan_jid in jids:
|
|
is_active = False
|
|
for active_data in active:
|
|
@@ -260,7 +254,7 @@ def soft_kill(jid, state_id=None):
|
|
salt '*' state.soft_kill 20171130110407769519
|
|
salt '*' state.soft_kill 20171130110407769519 vim
|
|
"""
|
|
- jid = six.text_type(jid)
|
|
+ jid = str(jid)
|
|
if state_id is None:
|
|
state_id = "__all__"
|
|
data, pause_path = _get_pause(jid, state_id)
|
|
@@ -294,7 +288,7 @@ def pause(jid, state_id=None, duration=None):
|
|
salt '*' state.pause 20171130110407769519 vim
|
|
salt '*' state.pause 20171130110407769519 vim 20
|
|
"""
|
|
- jid = six.text_type(jid)
|
|
+ jid = str(jid)
|
|
if state_id is None:
|
|
state_id = "__all__"
|
|
data, pause_path = _get_pause(jid, state_id)
|
|
@@ -326,7 +320,7 @@ def resume(jid, state_id=None):
|
|
salt '*' state.resume 20171130110407769519
|
|
salt '*' state.resume 20171130110407769519 vim
|
|
"""
|
|
- jid = six.text_type(jid)
|
|
+ jid = str(jid)
|
|
if state_id is None:
|
|
state_id = "__all__"
|
|
data, pause_path = _get_pause(jid, state_id)
|
|
@@ -387,8 +381,8 @@ def running(concurrent=False):
|
|
active = __salt__["saltutil.is_running"]("state.*")
|
|
for data in active:
|
|
err = (
|
|
- 'The function "{0}" is running as PID {1} and was started at '
|
|
- "{2} with jid {3}"
|
|
+ 'The function "{}" is running as PID {} and was started at '
|
|
+ "{} with jid {}"
|
|
).format(
|
|
data["fun"],
|
|
data["pid"],
|
|
@@ -850,10 +844,10 @@ def request(mods=None, **kwargs):
|
|
try:
|
|
if salt.utils.platform.is_windows():
|
|
# Make sure cache file isn't read-only
|
|
- __salt__["cmd.run"]('attrib -R "{0}"'.format(notify_path))
|
|
+ __salt__["cmd.run"]('attrib -R "{}"'.format(notify_path))
|
|
with salt.utils.files.fopen(notify_path, "w+b") as fp_:
|
|
serial.dump(req, fp_)
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
log.error(
|
|
"Unable to write state request file %s. Check permission.", notify_path
|
|
)
|
|
@@ -902,7 +896,7 @@ def clear_request(name=None):
|
|
if not name:
|
|
try:
|
|
os.remove(notify_path)
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
pass
|
|
else:
|
|
req = check_request()
|
|
@@ -914,10 +908,10 @@ def clear_request(name=None):
|
|
try:
|
|
if salt.utils.platform.is_windows():
|
|
# Make sure cache file isn't read-only
|
|
- __salt__["cmd.run"]('attrib -R "{0}"'.format(notify_path))
|
|
+ __salt__["cmd.run"]('attrib -R "{}"'.format(notify_path))
|
|
with salt.utils.files.fopen(notify_path, "w+b") as fp_:
|
|
serial.dump(req, fp_)
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
log.error(
|
|
"Unable to write state request file %s. Check permission.",
|
|
notify_path,
|
|
@@ -950,7 +944,7 @@ def run_request(name="default", **kwargs):
|
|
ret = apply_(n_req["mods"], **n_req["kwargs"])
|
|
try:
|
|
os.remove(os.path.join(__opts__["cachedir"], "req_state.p"))
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
pass
|
|
return ret
|
|
return {}
|
|
@@ -1319,7 +1313,7 @@ def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
|
|
serial = salt.payload.Serial(__opts__)
|
|
cfn = os.path.join(
|
|
__opts__["cachedir"],
|
|
- "{0}.cache.p".format(kwargs.get("cache_name", "highstate")),
|
|
+ "{}.cache.p".format(kwargs.get("cache_name", "highstate")),
|
|
)
|
|
|
|
if sync_mods is True:
|
|
@@ -1335,7 +1329,7 @@ def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
|
|
|
|
for module_type in sync_mods:
|
|
try:
|
|
- __salt__["saltutil.sync_{0}".format(module_type)](saltenv=opts["saltenv"])
|
|
+ __salt__["saltutil.sync_{}".format(module_type)](saltenv=opts["saltenv"])
|
|
except KeyError:
|
|
log.warning("Invalid custom module type '%s', ignoring", module_type)
|
|
|
|
@@ -1374,7 +1368,7 @@ def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
|
|
return st_.state.call_high(high_, orchestration_jid)
|
|
|
|
# If the state file is an integer, convert to a string then to unicode
|
|
- if isinstance(mods, six.integer_types):
|
|
+ if isinstance(mods, int):
|
|
mods = salt.utils.stringutils.to_unicode(
|
|
str(mods)
|
|
) # future lint: disable=blacklisted-function
|
|
@@ -1409,7 +1403,7 @@ def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
|
|
__salt__["cmd.run"](["attrib", "-R", cache_file], python_shell=False)
|
|
with salt.utils.files.fopen(cache_file, "w+b") as fp_:
|
|
serial.dump(ret, fp_)
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
log.error(
|
|
"Unable to write to SLS cache file %s. Check permission.", cache_file
|
|
)
|
|
@@ -1425,7 +1419,7 @@ def sls(mods, test=None, exclude=None, queue=False, sync_mods=None, **kwargs):
|
|
except TypeError:
|
|
# Can't serialize pydsl
|
|
pass
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
log.error(
|
|
"Unable to write to highstate cache file %s. Do you have permissions?",
|
|
cfn,
|
|
@@ -1830,8 +1824,8 @@ def sls_id(id_, mods, test=None, queue=False, **kwargs):
|
|
__opts__["test"] = orig_test
|
|
if not ret:
|
|
raise SaltInvocationError(
|
|
- "No matches for ID '{0}' found in SLS '{1}' within saltenv "
|
|
- "'{2}'".format(id_, mods, opts["saltenv"])
|
|
+ "No matches for ID '{}' found in SLS '{}' within saltenv "
|
|
+ "'{}'".format(id_, mods, opts["saltenv"])
|
|
)
|
|
return ret
|
|
|
|
@@ -2067,9 +2061,9 @@ def id_exists(ids, mods, test=None, queue=False, **kwargs):
|
|
"""
|
|
ids = salt.utils.args.split_input(ids)
|
|
ids = set(ids)
|
|
- sls_ids = set(
|
|
+ sls_ids = {
|
|
x["__id__"] for x in show_low_sls(mods, test=test, queue=queue, **kwargs)
|
|
- )
|
|
+ }
|
|
return ids.issubset(sls_ids)
|
|
|
|
|
|
@@ -2239,10 +2233,10 @@ def pkg(pkg_path, pkg_sum, hash_type, test=None, **kwargs):
|
|
members = s_pkg.getmembers()
|
|
for member in members:
|
|
if salt.utils.stringutils.to_unicode(member.path).startswith(
|
|
- (os.sep, "..{0}".format(os.sep))
|
|
+ (os.sep, "..{}".format(os.sep))
|
|
):
|
|
return {}
|
|
- elif "..{0}".format(os.sep) in salt.utils.stringutils.to_unicode(member.path):
|
|
+ elif "..{}".format(os.sep) in salt.utils.stringutils.to_unicode(member.path):
|
|
return {}
|
|
s_pkg.extractall(root)
|
|
s_pkg.close()
|
|
@@ -2282,7 +2276,7 @@ def pkg(pkg_path, pkg_sum, hash_type, test=None, **kwargs):
|
|
ret = st_.call_listen(lowstate, ret)
|
|
try:
|
|
shutil.rmtree(root)
|
|
- except (IOError, OSError):
|
|
+ except OSError:
|
|
pass
|
|
_set_retcode(ret)
|
|
_snapper_post(popts, kwargs.get("__pub_jid", "called localy"), snapper_pre)
|
|
@@ -2320,9 +2314,9 @@ def disable(states):
|
|
_changed = False
|
|
for _state in states:
|
|
if _state in _disabled:
|
|
- msg.append("Info: {0} state already disabled.".format(_state))
|
|
+ msg.append("Info: {} state already disabled.".format(_state))
|
|
else:
|
|
- msg.append("Info: {0} state disabled.".format(_state))
|
|
+ msg.append("Info: {} state disabled.".format(_state))
|
|
_disabled.append(_state)
|
|
_changed = True
|
|
|
|
@@ -2370,9 +2364,9 @@ def enable(states):
|
|
for _state in states:
|
|
log.debug("_state %s", _state)
|
|
if _state not in _disabled:
|
|
- msg.append("Info: {0} state already enabled.".format(_state))
|
|
+ msg.append("Info: {} state already enabled.".format(_state))
|
|
else:
|
|
- msg.append("Info: {0} state enabled.".format(_state))
|
|
+ msg.append("Info: {} state enabled.".format(_state))
|
|
_disabled.remove(_state)
|
|
_changed = True
|
|
|
|
@@ -2481,7 +2475,7 @@ def event(
|
|
if salt.utils.stringutils.expr_match(ret["tag"], tagmatch):
|
|
if not quiet:
|
|
salt.utils.stringutils.print_cli(
|
|
- str("{0}\t{1}").format( # future lint: blacklisted-function
|
|
+ "{}\t{}".format( # future lint: blacklisted-function
|
|
salt.utils.stringutils.to_str(ret["tag"]),
|
|
salt.utils.json.dumps(
|
|
ret["data"],
|
|
diff --git a/tests/unit/modules/test_state.py b/tests/unit/modules/test_state.py
|
|
index 157687c7e8..065b24a84d 100644
|
|
--- a/tests/unit/modules/test_state.py
|
|
+++ b/tests/unit/modules/test_state.py
|
|
@@ -1,8 +1,6 @@
|
|
-# -*- coding: utf-8 -*-
|
|
"""
|
|
:codeauthor: Rahul Handay <rahulha@saltstack.com>
|
|
"""
|
|
-from __future__ import absolute_import, print_function, unicode_literals
|
|
|
|
import copy
|
|
import os
|
|
@@ -32,7 +30,7 @@ from tests.support.runtests import RUNTIME_VARS
|
|
from tests.support.unit import TestCase
|
|
|
|
|
|
-class MockState(object):
|
|
+class MockState:
|
|
"""
|
|
Mock class
|
|
"""
|
|
@@ -40,7 +38,7 @@ class MockState(object):
|
|
def __init__(self):
|
|
pass
|
|
|
|
- class State(object):
|
|
+ class State:
|
|
"""
|
|
Mock state class
|
|
"""
|
|
@@ -129,7 +127,7 @@ class MockState(object):
|
|
def requisite_in(self, data): # pylint: disable=unused-argument
|
|
return data, []
|
|
|
|
- class HighState(object):
|
|
+ class HighState:
|
|
"""
|
|
Mock HighState class
|
|
"""
|
|
@@ -232,7 +230,7 @@ class MockState(object):
|
|
return True
|
|
|
|
|
|
-class MockSerial(object):
|
|
+class MockSerial:
|
|
"""
|
|
Mock Class
|
|
"""
|
|
@@ -240,7 +238,7 @@ class MockSerial(object):
|
|
def __init__(self):
|
|
pass
|
|
|
|
- class Serial(object):
|
|
+ class Serial:
|
|
"""
|
|
Mock Serial class
|
|
"""
|
|
@@ -263,7 +261,7 @@ class MockSerial(object):
|
|
return True
|
|
|
|
|
|
-class MockTarFile(object):
|
|
+class MockTarFile:
|
|
"""
|
|
Mock tarfile class
|
|
"""
|
|
@@ -950,57 +948,57 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
with patch.dict(state.__opts__, {test_arg: True}):
|
|
self.assertTrue(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is True in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is True in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {test_arg: "blah"}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is blah in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is blah in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {test_arg: "true"}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is true in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is true in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__opts__, {test_arg: False}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is False in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is False in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__opts__, {}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} does not exist in __opts__".format(test_arg),
|
|
+ msg="Failure when {} does not exist in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {test_arg: None}):
|
|
self.assertEqual(
|
|
state._get_test_value(test=None),
|
|
None,
|
|
- msg="Failure when {0} is None in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is None in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {test_arg: True}):
|
|
self.assertTrue(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is True in __pillar__".format(test_arg),
|
|
+ msg="Failure when {} is True in __pillar__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {"master": {test_arg: True}}):
|
|
self.assertTrue(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is True in master __pillar__".format(test_arg),
|
|
+ msg="Failure when {} is True in master __pillar__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(config.__pillar__, {"master": {test_arg: False}}):
|
|
with patch.dict(config.__pillar__, {test_arg: True}):
|
|
self.assertTrue(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is False in master __pillar__ and True in pillar".format(
|
|
+ msg="Failure when {} is False in master __pillar__ and True in pillar".format(
|
|
test_arg
|
|
),
|
|
)
|
|
@@ -1009,7 +1007,7 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
with patch.dict(config.__pillar__, {test_arg: False}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is True in master __pillar__ and False in pillar".format(
|
|
+ msg="Failure when {} is True in master __pillar__ and False in pillar".format(
|
|
test_arg
|
|
),
|
|
)
|
|
@@ -1017,14 +1015,14 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
with patch.dict(state.__opts__, {"test": False}):
|
|
self.assertFalse(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is False in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is False in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(state.__opts__, {"test": False}):
|
|
with patch.dict(config.__pillar__, {"master": {test_arg: True}}):
|
|
self.assertTrue(
|
|
state._get_test_value(test=None),
|
|
- msg="Failure when {0} is False in __opts__".format(test_arg),
|
|
+ msg="Failure when {} is False in __opts__".format(test_arg),
|
|
)
|
|
|
|
with patch.dict(state.__opts__, {}):
|
|
@@ -1077,7 +1075,7 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
expected = 1
|
|
assert (
|
|
call_count == expected
|
|
- ), "{0} called {1} time(s) (expected: {2})".format(
|
|
+ ), "{} called {} time(s) (expected: {})".format(
|
|
key, call_count, expected
|
|
)
|
|
|
|
@@ -1091,7 +1089,7 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
expected = 1
|
|
assert (
|
|
call_count == expected
|
|
- ), "{0} called {1} time(s) (expected: {2})".format(
|
|
+ ), "{} called {} time(s) (expected: {})".format(
|
|
key, call_count, expected
|
|
)
|
|
|
|
@@ -1105,7 +1103,7 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
expected = 1
|
|
assert (
|
|
call_count == expected
|
|
- ), "{0} called {1} time(s) (expected: {2})".format(
|
|
+ ), "{} called {} time(s) (expected: {})".format(
|
|
key, call_count, expected
|
|
)
|
|
|
|
@@ -1121,7 +1119,7 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
expected = 1
|
|
assert (
|
|
call_count == expected
|
|
- ), "{0} called {1} time(s) (expected: {2})".format(
|
|
+ ), "{} called {} time(s) (expected: {})".format(
|
|
key, call_count, expected
|
|
)
|
|
|
|
@@ -1168,15 +1166,8 @@ class StateTestCase(TestCase, LoaderModuleMockMixin):
|
|
state._format_cached_grains.assert_called_once()
|
|
|
|
MockTarFile.path = ""
|
|
- if six.PY2:
|
|
- with patch("salt.utils.files.fopen", mock_open()), patch.dict(
|
|
- state.__utils__,
|
|
- {"state.check_result": MagicMock(return_value=True)},
|
|
- ):
|
|
- self.assertTrue(state.pkg(tar_file, 0, "md5"))
|
|
- else:
|
|
- with patch("salt.utils.files.fopen", mock_open()):
|
|
- self.assertTrue(state.pkg(tar_file, 0, "md5"))
|
|
+ with patch("salt.utils.files.fopen", mock_open()):
|
|
+ self.assertTrue(state.pkg(tar_file, 0, "md5"))
|
|
|
|
def test_lock_saltenv(self):
|
|
"""
|
|
--
|
|
2.29.2
|
|
|
|
|