From 2ae9fa97c88889a1a99f0ccd43aea0fe996aad7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Su=C3=A1rez=20Hern=C3=A1ndez?= 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 """ -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