mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
Merge remote-tracking branch 'upstream/2015.5' into merge-forward-develop
Conflicts: salt/modules/win_file.py
This commit is contained in:
commit
2ae0d7d302
12 changed files with 269 additions and 28 deletions
3
AUTHORS
3
AUTHORS
|
@ -40,11 +40,13 @@ Christer Edwards <christer.edwards@gmail.com>
|
|||
Clint Savage <herlo1@gmail.com>
|
||||
Colton Myers <cmyers@saltstack.com>
|
||||
Corey Quinn <corey@sequestered.net>
|
||||
Corin Kochenower <ckochenower@saltstack.com>
|
||||
Dan Garthwaite <dan@garthwaite.org>
|
||||
Daniel Wallace <danielwallace at gtmanfred dot com>
|
||||
David Boucha <boucha@gmail.com>
|
||||
David Pravec <alekibango@pravec.tk>
|
||||
deutsche
|
||||
Dmitry Kuzmenko <dkuzmenko@saltstack.com>
|
||||
Doug Renn <renn@nestegg.com>
|
||||
Eivind Uggedal <eivind@uggedal.com>
|
||||
epoelke@gmail.com <epoelke@heartflow.com>
|
||||
|
@ -77,6 +79,7 @@ Matthew Printz <hipokrit@gmail.com>
|
|||
Matthias Teege <matthias-git@mteege.de>
|
||||
Maxim Burgerhout <maxim@wzzrd.com>
|
||||
Mickey Malone <mickey.malone@gmail.com>
|
||||
Michael Steed <msteed@saltstack.com>
|
||||
Mike Place <mp@saltstack.com>
|
||||
Mitch Anderson <mitch@metauser.net>
|
||||
Mostafa Hussein <mostafa.hussein91@gmail.com>
|
||||
|
|
|
@ -48,7 +48,8 @@
|
|||
|
||||
# The number of worker threads to start. These threads are used to manage
|
||||
# return calls made from minions to the master. If the master seems to be
|
||||
# running slowly, increase the number of threads.
|
||||
# running slowly, increase the number of threads. This setting can not be
|
||||
# set lower than 3.
|
||||
#worker_threads: 5
|
||||
|
||||
# The port used by the communication interface. The ret (return) port is the
|
||||
|
|
|
@ -118,6 +118,12 @@ https://groups.google.com/forum/#!forum/salt-users
|
|||
|
||||
.. _`salt-users mailing list`: https://groups.google.com/forum/#!forum/salt-users
|
||||
|
||||
There is also a low-traffic list used to announce new releases
|
||||
called `salt-announce`_
|
||||
|
||||
https://groups.google.com/forum/#!forum/salt-announce
|
||||
|
||||
.. _`salt-announce`: https://groups.google.com/forum/#!forum/salt-announce
|
||||
|
||||
IRC
|
||||
===
|
||||
|
|
|
@ -300,6 +300,8 @@ def get_conn():
|
|||
)
|
||||
else:
|
||||
actual_password = provider_password
|
||||
else:
|
||||
actual_password = driver_password
|
||||
else:
|
||||
actual_password = password
|
||||
return driver(
|
||||
|
|
|
@ -144,12 +144,11 @@ def has_target(alias, target):
|
|||
if target == '':
|
||||
raise SaltInvocationError('target can not be an empty string')
|
||||
aliases = list_aliases()
|
||||
if alias in aliases and isinstance(target, list):
|
||||
for item in target:
|
||||
if item not in aliases[alias]:
|
||||
return False
|
||||
if alias not in aliases:
|
||||
return False
|
||||
if isinstance(target, list):
|
||||
target = ', '.join(target)
|
||||
return alias in aliases and target in aliases[alias]
|
||||
return target == aliases[alias]
|
||||
|
||||
|
||||
def set_target(alias, target):
|
||||
|
|
|
@ -130,7 +130,8 @@ def execute(context=None, lens=None, commands=()):
|
|||
|
||||
try:
|
||||
if method == 'set':
|
||||
path, value, remainder = re.split('([^\'" ]+|"[^"]+"|\'[^\']+\')$', arg, 1)
|
||||
path, value, remainder = re.split('([^\'" ]+|"[^"]*"|\'[^\']*\')$', arg, 1)
|
||||
path = path.rstrip()
|
||||
if context:
|
||||
path = os.path.join(context.rstrip('/'), path.lstrip('/'))
|
||||
value = value.strip('"').strip("'")
|
||||
|
|
|
@ -984,13 +984,12 @@ def uncomment(path,
|
|||
|
||||
salt '*' file.uncomment /etc/hosts.deny 'ALL: PARANOID'
|
||||
'''
|
||||
# Largely inspired by Fabric's contrib.files.uncomment()
|
||||
|
||||
return sed(path,
|
||||
before=r'^([[:space:]]*){0}'.format(char),
|
||||
after=r'\1',
|
||||
limit=regex.lstrip('^'),
|
||||
backup=backup)
|
||||
pattern = '^{0}{1}'.format(char, regex.lstrip('^').rstrip('$'))
|
||||
repl = "{0}".format(regex.lstrip('^').rstrip('$'))
|
||||
return replace(path=path,
|
||||
pattern=pattern,
|
||||
repl=repl,
|
||||
backup=backup)
|
||||
|
||||
|
||||
def comment(path,
|
||||
|
@ -1028,17 +1027,11 @@ def comment(path,
|
|||
|
||||
salt '*' file.comment /etc/modules pcspkr
|
||||
'''
|
||||
# Largely inspired by Fabric's contrib.files.comment()
|
||||
|
||||
regex = '{0}({1}){2}'.format(
|
||||
'^' if regex.startswith('^') else '',
|
||||
regex.lstrip('^').rstrip('$'),
|
||||
'$' if regex.endswith('$') else '')
|
||||
|
||||
return sed(path,
|
||||
before=regex,
|
||||
after=r'{0}\1'.format(char),
|
||||
backup=backup)
|
||||
repl = "{0}{1}".format(char, regex.lstrip('^').rstrip('$'))
|
||||
return replace(path=path,
|
||||
pattern=regex,
|
||||
repl=repl,
|
||||
backup=backup)
|
||||
|
||||
|
||||
def _get_flags(flags):
|
||||
|
|
|
@ -58,7 +58,8 @@ from salt.modules.file import (check_hash, # pylint: disable=W0611
|
|||
access, copy, readdir, rmdir, truncate, replace, delete_backup,
|
||||
search, _get_flags, extract_hash, _error, _sed_esc, _psed,
|
||||
RE_FLAG_TABLE, blockreplace, prepend, seek_read, seek_write, rename,
|
||||
lstat, path_exists_glob, write, pardir, join, HASHES)
|
||||
lstat, path_exists_glob, write, pardir, join, HASHES, comment,
|
||||
uncomment)
|
||||
|
||||
from salt.utils import namespaced_function as _namespaced_function
|
||||
|
||||
|
@ -85,7 +86,7 @@ def __virtual__():
|
|||
global _binary_replace, _get_bkroot, list_backups, restore_backup
|
||||
global blockreplace, prepend, seek_read, seek_write, rename, lstat
|
||||
global write, pardir, join
|
||||
global path_exists_glob, _mkstemp_copy
|
||||
global path_exists_glob, comment, uncomment, _mkstemp_copy
|
||||
|
||||
replace = _namespaced_function(replace, globals())
|
||||
search = _namespaced_function(search, globals())
|
||||
|
@ -138,6 +139,8 @@ def __virtual__():
|
|||
write = _namespaced_function(write, globals())
|
||||
pardir = _namespaced_function(pardir, globals())
|
||||
join = _namespaced_function(join, globals())
|
||||
comment = _namespaced_function(comment, globals())
|
||||
uncomment = _namespaced_function(uncomment, globals())
|
||||
_mkstemp_copy = _namespaced_function(_mkstemp_copy, globals())
|
||||
|
||||
return __virtualname__
|
||||
|
|
|
@ -858,6 +858,9 @@ class State(object):
|
|||
data['__sls__']
|
||||
)
|
||||
)
|
||||
reason = self.states.missing_fun_string(full)
|
||||
if reason:
|
||||
errors.append('Reason: {0}'.format(reason))
|
||||
else:
|
||||
errors.append(
|
||||
'Specified state \'{0}\' was not found'.format(
|
||||
|
|
|
@ -31,7 +31,7 @@ def __virtual__():
|
|||
'''
|
||||
Only load if the npm module is available in __salt__
|
||||
'''
|
||||
return 'npm' if 'npm.list' in __salt__ else False
|
||||
return 'npm' if 'npm.list' in __salt__ else False, '\'npm\' binary not found on system'
|
||||
|
||||
|
||||
def installed(name,
|
||||
|
|
94
tests/unit/states/schedule_test.py
Normal file
94
tests/unit/states/schedule_test.py
Normal file
|
@ -0,0 +1,94 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import schedule
|
||||
|
||||
schedule.__opts__ = {}
|
||||
schedule.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class ScheduleTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.schedule
|
||||
'''
|
||||
# 'present' function tests: 1
|
||||
|
||||
def test_present(self):
|
||||
'''
|
||||
Test to ensure a job is present in the schedule.
|
||||
'''
|
||||
name = 'job1'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_dict = MagicMock(side_effect=[ret, []])
|
||||
mock_mod = MagicMock(return_value=ret)
|
||||
mock_lst = MagicMock(side_effect=[{name: {}}, {name: {}}, {}, {}])
|
||||
with patch.dict(schedule.__salt__,
|
||||
{'schedule.list': mock_lst,
|
||||
'schedule.build_schedule_item': mock_dict,
|
||||
'schedule.modify': mock_mod,
|
||||
'schedule.add': mock_mod}):
|
||||
self.assertDictEqual(schedule.present(name), ret)
|
||||
|
||||
with patch.dict(schedule.__opts__, {'test': False}):
|
||||
self.assertDictEqual(schedule.present(name), ret)
|
||||
|
||||
self.assertDictEqual(schedule.present(name), ret)
|
||||
|
||||
with patch.dict(schedule.__opts__, {'test': True}):
|
||||
ret.update({'result': True})
|
||||
self.assertDictEqual(schedule.present(name), ret)
|
||||
|
||||
# 'absent' function tests: 1
|
||||
|
||||
def test_absent(self):
|
||||
'''
|
||||
Test to ensure a job is absent from the schedule.
|
||||
'''
|
||||
name = 'job1'
|
||||
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_mod = MagicMock(return_value=ret)
|
||||
mock_lst = MagicMock(side_effect=[{name: {}}, {}])
|
||||
with patch.dict(schedule.__salt__,
|
||||
{'schedule.list': mock_lst,
|
||||
'schedule.delete': mock_mod}):
|
||||
with patch.dict(schedule.__opts__, {'test': False}):
|
||||
self.assertDictEqual(schedule.absent(name), ret)
|
||||
|
||||
with patch.dict(schedule.__opts__, {'test': True}):
|
||||
comt = ('Job job1 not present in schedule')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(schedule.absent(name), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(ScheduleTestCase, needs_daemon=False)
|
136
tests/unit/states/selinux_test.py
Normal file
136
tests/unit/states/selinux_test.py
Normal file
|
@ -0,0 +1,136 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
:codeauthor: :email:`Jayesh Kariya <jayeshk@saltstack.com>`
|
||||
'''
|
||||
# Import Python libs
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import skipIf, TestCase
|
||||
from salttesting.mock import (
|
||||
NO_MOCK,
|
||||
NO_MOCK_REASON,
|
||||
MagicMock,
|
||||
patch
|
||||
)
|
||||
|
||||
from salttesting.helpers import ensure_in_syspath
|
||||
|
||||
ensure_in_syspath('../../')
|
||||
|
||||
# Import Salt Libs
|
||||
from salt.states import selinux
|
||||
|
||||
selinux.__opts__ = {}
|
||||
selinux.__salt__ = {}
|
||||
|
||||
|
||||
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
||||
class SelinuxTestCase(TestCase):
|
||||
'''
|
||||
Test cases for salt.states.selinux
|
||||
'''
|
||||
# 'mode' function tests: 1
|
||||
|
||||
def test_mode(self):
|
||||
'''
|
||||
Test to verifies the mode SELinux is running in,
|
||||
can be set to enforcing or permissive.
|
||||
'''
|
||||
ret = {'name': '',
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
comt = ('unknown is not an accepted mode')
|
||||
ret.update({'name': 'unknown', 'comment': comt})
|
||||
self.assertDictEqual(selinux.mode('unknown'), ret)
|
||||
|
||||
mock_en = MagicMock(return_value='Enforcing')
|
||||
mock_pr = MagicMock(side_effect=['Permissive', 'Enforcing'])
|
||||
with patch.dict(selinux.__salt__,
|
||||
{'selinux.getenforce': mock_en,
|
||||
'selinux.setenforce': mock_pr}):
|
||||
comt = ('SELinux is already in Enforcing mode')
|
||||
ret.update({'name': 'Enforcing', 'comment': comt, 'result': True})
|
||||
self.assertDictEqual(selinux.mode('Enforcing'), ret)
|
||||
|
||||
with patch.dict(selinux.__opts__, {'test': True}):
|
||||
comt = ('SELinux mode is set to be changed to Permissive')
|
||||
ret.update({'name': 'Permissive', 'comment': comt,
|
||||
'result': None})
|
||||
self.assertDictEqual(selinux.mode('Permissive'), ret)
|
||||
|
||||
with patch.dict(selinux.__opts__, {'test': False}):
|
||||
comt = ('SELinux has been set to Permissive mode')
|
||||
ret.update({'name': 'Permissive', 'comment': comt,
|
||||
'result': True})
|
||||
self.assertDictEqual(selinux.mode('Permissive'), ret)
|
||||
|
||||
comt = ('Failed to set SELinux to Permissive mode')
|
||||
ret.update({'name': 'Permissive', 'comment': comt,
|
||||
'result': False})
|
||||
self.assertDictEqual(selinux.mode('Permissive'), ret)
|
||||
|
||||
# 'boolean' function tests: 1
|
||||
|
||||
def test_boolean(self):
|
||||
'''
|
||||
Test to set up an SELinux boolean.
|
||||
'''
|
||||
name = 'samba_create_home_dirs'
|
||||
value = True
|
||||
ret = {'name': name,
|
||||
'changes': {},
|
||||
'result': False,
|
||||
'comment': ''}
|
||||
|
||||
mock_en = MagicMock(return_value=[])
|
||||
with patch.dict(selinux.__salt__,
|
||||
{'selinux.list_sebool': mock_en}):
|
||||
comt = ('Boolean {0} is not available'.format(name))
|
||||
ret.update({'comment': comt})
|
||||
self.assertDictEqual(selinux.boolean(name, value), ret)
|
||||
|
||||
mock_bools = MagicMock(return_value={name: {'State': 'on',
|
||||
'Default': 'on'}})
|
||||
with patch.dict(selinux.__salt__,
|
||||
{'selinux.list_sebool': mock_bools}):
|
||||
comt = ('None is not a valid value for the boolean')
|
||||
ret.update({'comment': comt})
|
||||
self.assertDictEqual(selinux.boolean(name, None), ret)
|
||||
|
||||
comt = ('Boolean is in the correct state')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(selinux.boolean(name, value, True), ret)
|
||||
|
||||
comt = ('Boolean is in the correct state')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(selinux.boolean(name, value), ret)
|
||||
|
||||
mock_bools = MagicMock(return_value={name: {'State': 'off',
|
||||
'Default': 'on'}})
|
||||
mock = MagicMock(side_effect=[True, False])
|
||||
with patch.dict(selinux.__salt__,
|
||||
{'selinux.list_sebool': mock_bools,
|
||||
'selinux.setsebool': mock}):
|
||||
with patch.dict(selinux.__opts__, {'test': True}):
|
||||
comt = ('Boolean samba_create_home_dirs'
|
||||
' is set to be changed to on')
|
||||
ret.update({'comment': comt, 'result': None})
|
||||
self.assertDictEqual(selinux.boolean(name, value), ret)
|
||||
|
||||
with patch.dict(selinux.__opts__, {'test': False}):
|
||||
comt = ('Boolean samba_create_home_dirs has been set to on')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(selinux.boolean(name, value), ret)
|
||||
|
||||
comt = ('Failed to set the boolean '
|
||||
'samba_create_home_dirs to on')
|
||||
ret.update({'comment': comt, 'result': True})
|
||||
self.assertDictEqual(selinux.boolean(name, value), ret)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
from integration import run_tests
|
||||
run_tests(SelinuxTestCase, needs_daemon=False)
|
Loading…
Add table
Reference in a new issue