Merge remote-tracking branch 'upstream/2015.5' into merge-forward-develop

Conflicts:
    salt/modules/win_file.py
This commit is contained in:
Colton Myers 2015-06-16 15:13:53 -06:00
commit 2ae0d7d302
12 changed files with 269 additions and 28 deletions

View file

@ -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>

View file

@ -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

View file

@ -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
===

View file

@ -300,6 +300,8 @@ def get_conn():
)
else:
actual_password = provider_password
else:
actual_password = driver_password
else:
actual_password = password
return driver(

View file

@ -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):

View file

@ -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("'")

View file

@ -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):

View file

@ -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__

View file

@ -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(

View file

@ -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,

View 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)

View 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)