def run_contents_pillar(self, pillar_value, expected): returner = MagicMock(return_value=None) filestate.__salt__ = {'file.manage_file': returner} path = '/tmp/foo' pillar_path = 'foo:bar' # the values don't matter here filestate.__salt__['config.manage_mode'] = MagicMock() filestate.__salt__['file.source_list'] = MagicMock( return_value=[None, None]) filestate.__salt__['file.get_managed'] = MagicMock( return_value=[None, None, None]) # pillar.get should return the pillar_value pillar_mock = MagicMock(return_value=pillar_value) filestate.__salt__['pillar.get'] = pillar_mock ret = filestate.managed(path, contents_pillar=pillar_path) # make sure the pillar_mock is called with the given path pillar_mock.assert_called_once_with(pillar_path) # make sure no errors are returned self.assertEqual(None, ret) # make sure the value is correct self.assertEqual(expected, returner.call_args[0][-3])
def run_contents_pillar(self, pillar_value, expected): def returner(contents, *args, **kwargs): returner.returned = (contents, args, kwargs) returner.returned = None filestate.__salt__ = {"file.manage_file": returner} path = "/tmp/foo" pillar_path = "foo:bar" # the values don't matter here filestate.__salt__["config.manage_mode"] = MagicMock() filestate.__salt__["file.source_list"] = MagicMock(return_value=[None, None]) filestate.__salt__["file.get_managed"] = MagicMock(return_value=[None, None, None]) # pillar.get should return the pillar_value pillar_mock = MagicMock(return_value=pillar_value) filestate.__salt__["pillar.get"] = pillar_mock ret = filestate.managed(path, contents_pillar=pillar_path) # make sure the pillar_mock is called with the given path pillar_mock.assert_called_once_with(pillar_path) # make sure no errors are returned self.assertEquals(None, ret) # make sure the value is correct self.assertEquals(expected, returner.returned[1][-1])
def test_contents_pillar_doesnt_add_more_newlines(): # make sure the newline pillar_value = "i am the pillar value{}".format(os.linesep) returner = MagicMock(return_value=None) path = "/tmp/foo" pillar_path = "foo:bar" # the values don't matter here pillar_mock = MagicMock(return_value=pillar_value) with patch.dict( filestate.__salt__, { "file.manage_file": returner, "config.manage_mode": MagicMock(), "file.source_list": MagicMock(return_value=[None, None]), "file.get_managed": MagicMock(return_value=[None, None, None]), "pillar.get": pillar_mock, }, ): ret = filestate.managed(path, contents_pillar=pillar_path) # make sure no errors are returned assert ret is None # Make sure the contents value matches the expected value. # returner.call_args[0] will be an args tuple containing all the args # passed to the mocked returner for file.manage_file. Any changes to # the arguments for file.manage_file may make this assertion fail. # If the test is failing, check the position of the "contents" param # in the manage_file() function in salt/modules/file.py, the fix is # likely as simple as updating the 2nd index below. assert returner.call_args[0][-5] == pillar_value
def run_contents_pillar(self, pillar_value, expected): returner = MagicMock(return_value=None) filestate.__salt__ = { 'file.manage_file': returner } path = '/tmp/foo' pillar_path = 'foo:bar' # the values don't matter here filestate.__salt__['config.manage_mode'] = MagicMock() filestate.__salt__['file.source_list'] = MagicMock(return_value=[None, None]) filestate.__salt__['file.get_managed'] = MagicMock(return_value=[None, None, None]) # pillar.get should return the pillar_value pillar_mock = MagicMock(return_value=pillar_value) filestate.__salt__['pillar.get'] = pillar_mock ret = filestate.managed(path, contents_pillar=pillar_path) # make sure the pillar_mock is called with the given path pillar_mock.assert_called_once_with(pillar_path) # make sure no errors are returned self.assertEqual(None, ret) # make sure the value is correct self.assertEqual(expected, returner.call_args[0][-2])
def test_selinux_change(): file_name = "/tmp/some-test-file" check_perms_result = [ { "comment": "The file {} is set to be changed".format(file_name), "changes": { "selinux": { "New": "User: unconfined_u Type: lost_found_t", "Old": "User: system_u Type: user_tmp_t", } }, "name": file_name, "result": True, }, {"luser": "******", "lmode": "0644", "lgroup": "root"}, ] with patch.object(os.path, "exists", MagicMock(return_value=True)): with patch.dict( filestate.__salt__, { "file.source_list": MagicMock(return_value=[file_name, None]), "file.check_perms": MagicMock(return_value=check_perms_result), }, ): ret = filestate.managed( file_name, selinux={"seuser": "******", "setype": "user_tmp_t"}, ) assert ret["result"]
def test_contents_and_contents_pillar(self): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None filestate.__salt__ = {"file.manage_file": returner} manage_mode_mock = MagicMock() filestate.__salt__["config.manage_mode"] = manage_mode_mock ret = filestate.managed("/tmp/foo", contents="hi", contents_pillar="foo:bar") self.assertEquals(False, ret["result"])
def test_contents_and_contents_pillar(self): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None filestate.__salt__ = { 'file.manage_file': returner } manage_mode_mock = MagicMock() filestate.__salt__['config.manage_mode'] = manage_mode_mock ret = filestate.managed('/tmp/foo', contents='hi', contents_pillar='foo:bar') self.assertEqual(False, ret['result'])
def test_contents_and_contents_pillar(self): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None filestate.__salt__ = { 'file.manage_file': returner } manage_mode_mock = MagicMock() filestate.__salt__['config.manage_mode'] = manage_mode_mock ret = filestate.managed('/tmp/foo', contents='hi', contents_pillar='foo:bar') self.assertEquals(False, ret['result'])
def test_file_managed_should_fall_back_to_binary(): expected_contents = b"\x8b" filename = "/tmp/blarg" mock_manage = MagicMock(return_value={"fnord": "fnords"}) with patch("salt.states.file._load_accumulators", MagicMock(return_value=([], []))): with patch.dict( filestate.__salt__, { "file.get_managed": MagicMock(return_value=["", "", ""]), "file.source_list": MagicMock(return_value=["", ""]), "file.manage_file": mock_manage, "pillar.get": MagicMock(return_value=expected_contents), }, ): ret = filestate.managed(filename, contents_pillar="fnord", encoding="utf-8") actual_contents = mock_manage.call_args[0][14] assert actual_contents == expected_contents
def managed(name, onlyif=None, unless=None, user=None, group=None, env=None, **kwargs): """Manages a given file. Defers to salt.states.file.managed. Only executes onlyif is satisfied or the unless is not satisfied. """ user, env, group = kwargs.get('user'), kwargs.get('env'), kwargs.get('group') cret = _run_check(onlyif, unless, user, env) if isinstance(cret, dict): cret.update({'name': name}) return cret from salt.states import file as f f.__salt__ = __salt__ f.__opts__ = __opts__ f.__pillar__ = __pillar__ f.__grains__ = __grains__ return f.managed(name, **kwargs)
def test_contents_and_contents_pillar(): def returner(contents, *args, **kwargs): returner.returned = contents returner.returned = None manage_mode_mock = MagicMock() with patch.dict( filestate.__salt__, { "file.manage_file": returner, "config.manage_mode": manage_mode_mock }, ): ret = filestate.managed("/tmp/foo", contents="hi", contents_pillar="foo:bar") assert not ret["result"]
def managed( name, conf_dir='/etc/salt', cloud_servers_pillar=None, cloud_providers_pillar=None, cloud_defaults_pillar=None, file_mode='0600', dir_mode='0700', user='******', group='root', test=False ): from salt.states import file file.__instance_id__ = str(id(managed)) file.__env__ = __env__ file.__opts__ = __opts__ file.__salt__ = __salt__ ret = { 'name': name, 'result': False, 'comment': '', 'changes': {}, } comments = [] results = [] changes = {} provider_path = os.path.join(conf_dir, 'cloud.providers.d') profile_path = os.path.join(conf_dir, 'cloud.profiles.d') map_path = os.path.join(conf_dir, 'cloud.maps') cloud_servers = __salt__['pillar.get'](cloud_servers_pillar) cloud_providers = __salt__['pillar.get'](cloud_providers_pillar) cloud_defaults = __salt__['pillar.get'](cloud_defaults_pillar) providers, profiles, maps = __salt__['simplecloud.consume_map']( cloud_providers, cloud_servers, cloud_defaults ) provider_dir_results = file.directory( provider_path, user=user, group=group, dir_mode=dir_mode, test=test ) comments.append(provider_dir_results['comment']) results.append(provider_dir_results['result']) if provider_dir_results['changes']: changes[provider_path] = provider_dir_results['changes'] profile_dir_results = file.directory( profile_path, user=user, group=group, dir_mode=dir_mode, test=test ) comments.append(profile_dir_results['comment']) results.append(profile_dir_results['result']) if profile_dir_results['changes']: changes[profile_path] = profile_dir_results['changes'] map_dir_results = file.directory( map_path, user=user, group=group, dir_mode=dir_mode, test=test ) comments.append(map_dir_results['comment']) results.append(map_dir_results['result']) if map_dir_results['changes']: changes[map_path] = map_dir_results['changes'] for provider_name, provider in providers.items(): provider_data = {provider_name: provider} provider_file = os.path.join(provider_path, '%s.conf' % provider_name) source = _ordered_dump(provider_data, default_flow_style=False) provider_results = file.managed( provider_file, user=user, group=group, mode=file_mode, contents=source, test=test ) comments.append(provider_results['comment']) results.append(provider_results['result']) if provider_results['changes']: changes[provider_file] = provider_results['changes'] for env_name, profile_data in profiles.items(): profile_file = os.path.join(profile_path, '%s.conf' % env_name) source = _ordered_dump(profile_data, default_flow_style=False) profile_results = file.managed( profile_file, user=user, group=group, mode=file_mode, contents=source, test=test ) comments.append(profile_results['comment']) results.append(profile_results['result']) if profile_results['changes']: changes[profile_file] = profile_results['changes'] for env_name, map_data in maps.items(): map_file = os.path.join(map_path, env_name) source = _ordered_dump(map_data, default_flow_style=False) map_results = file.managed( map_file, user=user, group=group, mode=file_mode, contents=source, test=test ) comments.append(map_results['comment']) results.append(map_results['result']) if map_results['changes']: changes[map_file] = map_results['changes'] ret['changes'] = {s: c for s, c in changes.items() if c} ret['comment'] = '\n'.join([c for c in comments if c]) ret['result'] = all(results) return ret
def test_managed(): """ Test to manage a given file, this function allows for a file to be downloaded from the salt master and potentially run through a templating system. """ with patch("salt.states.file._load_accumulators", MagicMock(return_value=([], []))): name = "/etc/grub.conf" user = "******" group = "saltstack" ret = {"name": name, "result": False, "comment": "", "changes": {}} mock_t = MagicMock(return_value=True) mock_f = MagicMock(return_value=False) mock_cmd_fail = MagicMock(return_value={"retcode": 1}) mock_uid = MagicMock(side_effect=[ "", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", "U12", ]) mock_gid = MagicMock(side_effect=[ "", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", "G12", ]) mock_if = MagicMock(side_effect=[ True, False, False, False, False, False, False, False, False ]) if salt.utils.platform.is_windows(): mock_ret = MagicMock(return_value=ret) else: mock_ret = MagicMock(return_value=(ret, None)) mock_dict = MagicMock(return_value={}) mock_cp = MagicMock(side_effect=[Exception, True]) mock_ex = MagicMock(side_effect=[ Exception, { "changes": { name: name } }, True, Exception ]) mock_mng = MagicMock(side_effect=[ Exception, ("", "", ""), ("", "", ""), ("", "", True), ("", "", True), ("", "", ""), ("", "", ""), ("", "", ""), ]) mock_file = MagicMock(side_effect=[ CommandExecutionError, ("", ""), ("", ""), ("", ""), ("", ""), ("", ""), ("", ""), ("", ""), ("", ""), ("", ""), ]) with patch.dict( filestate.__salt__, { "config.manage_mode": mock_t, "file.user_to_uid": mock_uid, "file.group_to_gid": mock_gid, "file.file_exists": mock_if, "file.check_perms": mock_ret, "file.check_managed_changes": mock_dict, "file.get_managed": mock_mng, "file.source_list": mock_file, "file.copy": mock_cp, "file.manage_file": mock_ex, "cmd.run_all": mock_cmd_fail, }, ): comt = "Destination file name is required" ret.update({"comment": comt, "name": "", "changes": {}}) assert filestate.managed("") == ret with patch.object(os.path, "isfile", mock_f): comt = "File {} is not present and is not set for creation".format( name) ret.update({"comment": comt, "name": name, "result": True}) assert filestate.managed(name, create=False) == ret # Group argument is ignored on Windows systems. Group is set to # user if salt.utils.platform.is_windows(): comt = "User salt is not available Group salt is not available" else: comt = "User salt is not available Group saltstack is not available" ret.update({"comment": comt, "result": False}) assert filestate.managed(name, user=user, group=group) == ret with patch.object(os.path, "isabs", mock_f): comt = "Specified file {} is not an absolute path".format(name) ret.update({"comment": comt, "result": False}) assert filestate.managed(name, user=user, group=group) == ret with patch.object(os.path, "isabs", mock_t): with patch.object(os.path, "isdir", mock_t): comt = "Specified target {} is a directory".format(name) ret.update({"comment": comt}) assert filestate.managed(name, user=user, group=group) == ret with patch.object(os.path, "isdir", mock_f): comt = "Context must be formed as a dict" ret.update({"comment": comt}) assert (filestate.managed(name, user=user, group=group, context=True) == ret) comt = "Defaults must be formed as a dict" ret.update({"comment": comt}) assert (filestate.managed(name, user=user, group=group, defaults=True) == ret) comt = ("Only one of 'contents', 'contents_pillar', " "and 'contents_grains' is permitted") ret.update({"comment": comt}) assert (filestate.managed( name, user=user, group=group, contents="A", contents_grains="B", contents_pillar="C", ) == ret) with patch.object(os.path, "exists", mock_t): with patch.dict(filestate.__opts__, {"test": True}): comt = "File {} not updated".format(name) ret.update({"comment": comt}) assert (filestate.managed(name, user=user, group=group, replace=False) == ret) comt = "The file {} is in the correct state".format( name) ret.update({"comment": comt, "result": True}) assert (filestate.managed(name, user=user, contents="A", group=group) == ret) with patch.object(os.path, "exists", mock_f): with patch.dict(filestate.__opts__, {"test": False}): comt = "Unable to manage file: " ret.update({"comment": comt, "result": False}) assert (filestate.managed(name, user=user, group=group, contents="A") == ret) comt = "Unable to manage file: " ret.update({"comment": comt, "result": False}) assert (filestate.managed(name, user=user, group=group, contents="A") == ret) with patch.object(salt.utils.files, "mkstemp", return_value=name): comt = "Unable to copy file {0} to {0}: ".format( name) ret.update({"comment": comt, "result": False}) assert (filestate.managed( name, user=user, group=group, check_cmd="A") == ret) comt = "Unable to check_cmd file: " ret.update({"comment": comt, "result": False}) assert (filestate.managed(name, user=user, group=group, check_cmd="A") == ret) comt = "check_cmd execution failed" ret.update({ "comment": comt, "result": False, "skip_watch": True }) assert (filestate.managed(name, user=user, group=group, check_cmd="A") == ret) comt = "check_cmd execution failed" ret.update({"comment": True, "changes": {}}) ret.pop("skip_watch", None) assert (filestate.managed(name, user=user, group=group) == ret) assert filestate.managed(name, user=user, group=group) comt = "Unable to manage file: " ret.update({"comment": comt}) assert (filestate.managed(name, user=user, group=group) == ret) if salt.utils.platform.is_windows(): mock_ret = MagicMock(return_value=ret) comt = "File {} not updated".format(name) else: perms = { "luser": user, "lmode": "0644", "lgroup": group } mock_ret = MagicMock(return_value=(ret, perms)) comt = ("File {} will be updated with " "permissions 0400 from its current " "state of 0644".format(name)) with patch.dict(filestate.__salt__, {"file.check_perms": mock_ret}): with patch.object(os.path, "exists", mock_t): with patch.dict(filestate.__opts__, {"test": True}): ret.update({"comment": comt}) if salt.utils.platform.is_windows(): assert (filestate.managed( name, user=user, group=group) == ret) else: assert (filestate.managed(name, user=user, group=group, mode=400) == ret) # Replace is False, test is True, mode is empty # should return "File not updated" # https://github.com/saltstack/salt/issues/59276 if salt.utils.platform.is_windows(): mock_ret = MagicMock(return_value=ret) else: perms = { "luser": user, "lmode": "0644", "lgroup": group } mock_ret = MagicMock(return_value=(ret, perms)) comt = "File {} not updated".format(name) with patch.dict(filestate.__salt__, {"file.check_perms": mock_ret}): with patch.object(os.path, "exists", mock_t): with patch.dict(filestate.__opts__, {"test": True}): ret.update({"comment": comt}) if salt.utils.platform.is_windows(): assert (filestate.managed( name, user=user, group=group) == ret) else: assert (filestate.managed( name, user=user, group=group) == ret)