Merge branch '2016.3' into 'develop'

Conflicts:
  - salt/state.py
  - tests/integration/__init__.py
  - tests/integration/wheel/key.py
This commit is contained in:
rallytime 2016-07-26 11:05:24 -06:00
commit 76e8dd974a
24 changed files with 334 additions and 80 deletions

View file

@ -309,6 +309,11 @@
# running any commands. It would also blacklist any use of the "cmd"
# module. This is completely disabled by default.
#
#
# Check the list of configured users in client ACL against users on the
# system and throw errors if they do not exist.
#client_acl_verify: True
#
#publisher_acl_blacklist:
# users:
# - root

View file

@ -113,6 +113,20 @@ Pillar data. Make sure that your Pillars which need to use the string versions
of these values are enclosed in quotes. Pillars will be parsed twice by salt,
so you'll need to wrap your values in multiple quotes, for example '"false"'.
The '%' Sign
============
The `%` symbol has a special meaning in YAML, it needs to be passed as a
string literal:
.. code-block:: yaml
cheese:
ssh_auth.present:
- user: tbortels
- source: salt://ssh_keys/chease.pub
- config: '%h/.ssh/authorized_keys'
Integers are Parsed as Integers
===============================

View file

@ -23,6 +23,7 @@ class Beacon(object):
'''
def __init__(self, opts, functions):
self.opts = opts
self.functions = functions
self.beacons = salt.loader.beacons(opts, functions)
self.interval_map = dict()
@ -187,7 +188,8 @@ class Beacon(object):
'''
# Fire the complete event back along with the list of beacons
evt = salt.utils.event.get_event('minion', opts=self.opts)
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
b_conf = self.functions['config.merge']('beacons')
evt.fire_event({'complete': True, 'beacons': b_conf},
tag='/salt/minion/minion_beacons_list_complete')
return True

View file

@ -738,7 +738,8 @@ class Single(object):
'root_dir': os.path.join(self.thin_dir, 'running_data'),
'id': self.id,
'sock_dir': '/',
'log_file': 'salt-call.log'
'log_file': 'salt-call.log',
'fileserver_list_cache_time': 3,
})
self.minion_config = salt.serializers.yaml.serialize(self.minion_opts)
self.target = kwargs

View file

@ -154,7 +154,9 @@ def low(data, **kwargs):
__pillar__,
__salt__,
__context__['fileclient'])
err = st_.verify_data(data)
for chunk in chunks:
chunk['__id__'] = chunk['name'] if not chunk.get('__id__') else chunk['__id__']
err = st_.state.verify_data(data)
if err:
return err
file_refs = salt.client.ssh.state.lowstate_file_refs(
@ -223,7 +225,7 @@ def high(data, **kwargs):
__pillar__,
__salt__,
__context__['fileclient'])
chunks = st_.state.compile_high_data(high)
chunks = st_.state.compile_high_data(data)
file_refs = salt.client.ssh.state.lowstate_file_refs(
chunks,
_merge_extra_filerefs(

View file

@ -603,6 +603,7 @@ VALID_OPTS = {
'syndic_failover': str,
'runner_dirs': list,
'client_acl': dict,
'client_acl_verify': bool,
'client_acl_blacklist': dict,
'publisher_acl': dict,
'publisher_acl_blacklist': dict,
@ -1223,6 +1224,7 @@ DEFAULT_MASTER_OPTS = {
'runner_dirs': [],
'outputter_dirs': [],
'client_acl': {},
'client_acl_verify': True,
'client_acl_blacklist': {},
'publisher_acl': {},
'publisher_acl_blacklist': {},

View file

@ -246,9 +246,11 @@ def access_keys(opts):
if opts.get('user'):
acl_users.add(opts['user'])
acl_users.add(salt.utils.get_user())
if HAS_PWD:
if opts['client_acl_verify'] and HAS_PWD:
log.profile('Beginning pwd.getpwall() call in masterarpi acess_keys function')
for user in pwd.getpwall():
users.append(user.pw_name)
log.profile('End pwd.getpwall() call in masterarpi acess_keys function')
for user in acl_users:
log.info(
'Preparing the {0} key for local communication'.format(
@ -256,10 +258,12 @@ def access_keys(opts):
)
)
if HAS_PWD:
if opts['client_acl_verify'] and HAS_PWD:
if user not in users:
try:
log.profile('Beginning pwd.getpnam() call in masterarpi acess_keys function')
user = pwd.getpwnam(user).pw_name
log.profile('Beginning pwd.getpwnam() call in masterarpi acess_keys function')
except KeyError:
log.error('ACL user {0} is not available'.format(user))
continue

View file

@ -1149,6 +1149,7 @@ def os_data():
grains['osrelease'] = 'proxy'
grains['os'] = 'proxy'
grains['os_family'] = 'proxy'
grains['osfullname'] = 'proxy'
elif salt.utils.is_windows():
with salt.utils.winapi.Com():
wmi_c = wmi.WMI()

View file

@ -631,6 +631,19 @@ def setup_logfile_logger(log_path, log_level='error', log_format=None,
shutdown_multiprocessing_logging_listener()
sys.exit(2)
else:
# make sure, the logging directory exists and attempt to create it if necessary
log_dir = os.path.dirname(log_path)
if not os.path.exists(log_dir):
logging.getLogger(__name__).info(
'Log directory not found, trying to create it: {0}'.format(log_dir)
)
try:
os.makedirs(log_dir, mode=0o700)
except OSError as ose:
logging.getLogger(__name__).warning(
'Failed to create directory for log file: {0} ({1})'.format(log_dir, ose)
)
return
try:
# Logfile logging is UTF-8 on purpose.
# Since salt uses YAML and YAML uses either UTF-8 or UTF-16, if a

View file

@ -2318,7 +2318,7 @@ class ClearFuncs(object):
# always write out to the master job caches
try:
fstr = '{0}.save_load'.format(self.opts['master_job_cache'])
self.mminion.returners[fstr](clear_load['jid'], clear_load)
self.mminion.returners[fstr](clear_load['jid'], clear_load, minions)
except KeyError:
log.critical(
'The specified returner used for the master job cache '

View file

@ -9,13 +9,16 @@ Module for managing the Salt beacons on a minion
# Import Python libs
from __future__ import absolute_import
import difflib
import logging
import os
import yaml
# Import Salt libs
import salt.utils
import salt.utils.event
from salt.ext.six.moves import map
import logging
# Get logging started
log = logging.getLogger(__name__)
__func_alias__ = {
@ -38,6 +41,7 @@ def list_(return_yaml=True):
salt '*' beacons.list
'''
beacons = None
try:
eventer = salt.utils.event.get_event('minion', opts=__opts__)

View file

@ -1382,6 +1382,145 @@ def describe(cwd, rev='HEAD', user=None, ignore_retcode=False):
ignore_retcode=ignore_retcode)['stdout']
def diff(cwd,
item1=None,
item2=None,
opts='',
user=None,
no_index=False,
cached=False,
paths=None):
'''
.. versionadded:: 2015.8.12,2016.3.3
Interface to `git-diff(1)`_
cwd
The path to the git checkout
item1 and item2
Revision(s) to pass to the ``git diff`` command. One or both of these
arguments may be ignored if some of the options below are set to
``True``. When ``cached`` is ``False``, and no revisions are passed
to this function, then the current working tree will be compared
against the index (i.e. unstaged changes). When two revisions are
passed, they will be compared to each other.
opts
Any additional options to add to the command line, in a single string
.. note::
On the Salt CLI, if the opts are preceded with a dash, it is
necessary to precede them with ``opts=`` (as in the CLI examples
below) to avoid causing errors with Salt's own argument parsing.
user
User under which to run the git command. By default, the command is run
by the user under which the minion is running.
no_index : False
When it is necessary to diff two files in the same repo against each
other, and not diff two different revisions, set this option to
``True``. If this is left ``False`` in these instances, then a normal
``git diff`` will be performed against the index (i.e. unstaged
changes), and files in the ``paths`` option will be used to narrow down
the diff output.
.. note::
Requires Git 1.5.1 or newer. Additionally, when set to ``True``,
``item1`` and ``item2`` will be ignored.
cached : False
If ``True``, compare staged changes to ``item1`` (if specified),
otherwise compare them to the most recent commit.
.. note::
``item2`` is ignored if this option is is set to ``True``.
paths
File paths to pass to the ``git diff`` command. Can be passed as a
comma-separated list or a Python list.
.. _`git-diff(1)`: http://git-scm.com/docs/git-diff
CLI Example:
.. code-block:: bash
# Perform diff against the index (staging area for next commit)
salt myminion git.diff /path/to/repo
# Compare staged changes to the most recent commit
salt myminion git.diff /path/to/repo cached=True
# Compare staged changes to a specific revision
salt myminion git.diff /path/to/repo mybranch cached=True
# Perform diff against the most recent commit (includes staged changes)
salt myminion git.diff /path/to/repo HEAD
# Diff two commits
salt myminion git.diff /path/to/repo abcdef1 aabbccd
# Diff two commits, only showing differences in the specified paths
salt myminion git.diff /path/to/repo abcdef1 aabbccd paths=path/to/file1,path/to/file2
# Diff two files with one being outside the working tree
salt myminion git.diff /path/to/repo no_index=True paths=path/to/file1,/absolute/path/to/file2
'''
if no_index and cached:
raise CommandExecutionError(
'The \'no_index\' and \'cached\' options cannot be used together'
)
command = ['git', 'diff']
command.extend(_format_opts(opts))
if paths is not None and not isinstance(paths, (list, tuple)):
try:
paths = paths.split(',')
except AttributeError:
paths = str(paths).split(',')
ignore_retcode = False
failhard = True
if no_index:
if _LooseVersion(version(versioninfo=False)) < _LooseVersion('1.5.1'):
raise CommandExecutionError(
'The \'no_index\' option is only supported in Git 1.5.1 and '
'newer'
)
ignore_retcode = True
failhard = False
command.append('--no-index')
for value in [x for x in (item1, item2) if x]:
log.warning(
'Revision \'%s\' ignored in git diff, as revisions cannot be '
'used when no_index=True', value
)
elif cached:
command.append('--cached')
if item1:
command.append(item1)
if item2:
log.warning(
'Second revision \'%s\' ignored in git diff, at most one '
'revision is considered when cached=True', item2
)
else:
for value in [x for x in (item1, item2) if x]:
command.append(value)
if paths:
command.append('--')
command.extend(paths)
return _git_run(command,
cwd=cwd,
runas=user,
ignore_retcode=ignore_retcode,
failhard=failhard,
redirect_stderr=True)['stdout']
def fetch(cwd,
remote=None,
force=False,

View file

@ -61,11 +61,10 @@ def __virtual__():
'OEL',
'SUSE Enterprise Server',
'SUSE',
'McAfee OS Server'
'McAfee OS Server',
'VirtuozzoLinux'
))
if __grains__['os'] in enable:
if __grains__['os'] == 'XenServer':
return __virtualname__
if __grains__['os'] == 'SUSE':
if str(__grains__['osrelease']).startswith('11'):
@ -75,6 +74,15 @@ def __virtual__():
osrelease_major = __grains__.get('osrelease_info', [0])[0]
if __grains__['os'] == 'XenServer':
if osrelease_major >= 7:
return (
False,
'XenServer >= 7 uses systemd, will not load rh_service.py '
'as virtual \'service\''
)
return __virtualname__
if __grains__['os'] == 'Fedora':
if osrelease_major >= 15:
return (

View file

@ -52,7 +52,7 @@ def __virtual__():
except Exception:
return (False, 'The rpm execution module failed to load: failed to detect os or os_family grains.')
enabled = ('amazon', 'xcp', 'xenserver')
enabled = ('amazon', 'xcp', 'xenserver', 'VirtuozzoLinux')
if os_family in ['redhat', 'suse'] or os_grain in enabled:
return __virtualname__

View file

@ -160,7 +160,7 @@ def list_upgrades(refresh=True, saltenv='base', **kwargs): # pylint: disable=W0
ret = {}
for name, data in six.iteritems(get_repo_data(saltenv).get('repo', {})):
if version(name):
latest = latest_version(name)
latest = latest_version(name, refresh=False)
if latest:
ret[name] = latest
return ret
@ -663,7 +663,7 @@ def install(name=None, refresh=False, pkgs=None, saltenv='base', **kwargs):
version_num = _get_latest_pkg_version(pkginfo)
# Check if the version is already installed
if version_num == old.get(pkg_name) \
if version_num in old.get(pkg_name, '').split(',') \
or (pkg_name in old and old[pkg_name] == 'Not Found'):
# Desired version number already installed
ret[pkg_name] = {'current': version_num}
@ -981,7 +981,7 @@ def remove(name=None, pkgs=None, version=None, saltenv='base', **kwargs):
ret[target] = {'current': 'not installed'}
continue
else:
if not version_num == old.get(target) \
if version_num not in old.get(target, '').split(',') \
and not old.get(target) == "Not Found" \
and version_num != 'latest':
log.error('{0} {1} not installed'.format(target, version))

View file

@ -51,7 +51,6 @@ import salt.utils.yamlloader as yamlloader
# pylint: disable=import-error,no-name-in-module,redefined-builtin
import salt.ext.six as six
from salt.ext.six.moves import map, range, reload_module
from salt.ext.six import string_types
# pylint: enable=import-error,no-name-in-module,redefined-builtin
log = logging.getLogger(__name__)
@ -791,7 +790,7 @@ class State(object):
else:
low_data_onlyif = low_data['onlyif']
for entry in low_data_onlyif:
if not isinstance(entry, string_types):
if not isinstance(entry, six.string_types):
ret.update({'comment': 'onlyif execution failed, bad type passed', 'result': False})
return ret
cmd = self.functions['cmd.retcode'](
@ -812,7 +811,7 @@ class State(object):
else:
low_data_unless = low_data['unless']
for entry in low_data_unless:
if not isinstance(entry, string_types):
if not isinstance(entry, six.string_types):
ret.update({'comment': 'unless execution failed, bad type passed', 'result': False})
return ret
cmd = self.functions['cmd.retcode'](

View file

@ -177,17 +177,24 @@ def _failed_submodule_update(ret, exc, comments=None):
return _fail(ret, msg, comments)
def _not_fast_forward(ret, pre, post, branch, local_branch, comments):
def _not_fast_forward(ret, pre, post, branch, local_branch,
local_changes, comments):
pre = _short_sha(pre)
post = _short_sha(post)
return _fail(
ret,
'Repository would be updated from {0} to {1}{2}, but this is not a '
'fast-forward merge. Set \'force_reset\' to True to force this '
'update.'.format(
_short_sha(pre),
_short_sha(post),
'Repository would be updated {0}{1}, but {2}. Set \'force_reset\' to '
'True to force this update{3}.'.format(
'from {0} to {1}'.format(pre, post)
if local_changes and pre != post
else 'to {0}'.format(post),
' (after checking out local branch \'{0}\')'.format(branch)
if _need_branch_change(branch, local_branch)
else ''
else '',
'this is not a fast-forward merge'
if not local_changes
else 'there are uncommitted changes',
' and discard these changes' if local_changes else ''
),
comments
)
@ -730,6 +737,19 @@ def latest(name,
redact_auth=False)
revs_match = _revs_equal(local_rev, remote_rev, remote_rev_type)
try:
local_changes = bool(
__salt__['git.diff'](target, 'HEAD', user=user)
)
except CommandExecutionError:
# No need to capture the error and log it, the _git_run()
# helper in the git execution module will have already logged
# the output from the command.
log.warning(
'git.latest: Unable to determine if %s has local changes',
target
)
local_changes = False
if remote_rev_type == 'sha1' \
and base_rev is not None \
@ -819,13 +839,15 @@ def latest(name,
elif remote_rev_type == 'sha1':
has_remote_rev = True
if not has_remote_rev:
# Either the remote rev could not be found with git
# ls-remote (in which case we won't know more until
# fetching) or we're going to be checking out a new branch
# and don't have to worry about fast-forwarding.
fast_forward = None
else:
# If has_remote_rev is False, then either the remote rev could not
# be found with git ls-remote (in which case we won't know more
# until fetching) or we're going to be checking out a new branch
# and don't have to worry about fast-forwarding. So, we will set
# fast_forward to None (to signify uncertainty) unless there are
# local changes, in which case we will set it to False.
fast_forward = None if not local_changes else False
if has_remote_rev:
# Remote rev already present
if (not revs_match and not update_head) \
and (branch is None or branch == local_branch):
@ -839,14 +861,18 @@ def latest(name,
)
return ret
# No need to check if this is a fast_forward if we already know
# that it won't be (due to local changes).
if fast_forward is not False:
if base_rev is None:
# If we're here, the remote_rev exists in the local
# checkout but there is still no HEAD locally. A possible
# reason for this is that an empty repository existed there
# and a remote was added and fetched, but the repository
# was not fast-forwarded. Regardless, going from no HEAD to
# a locally-present rev is considered a fast-forward update.
fast_forward = True
# a locally-present rev is considered a fast-forward
# update, unless there are local changes.
fast_forward = not bool(local_changes)
else:
fast_forward = __salt__['git.merge_base'](
target,
@ -863,6 +889,7 @@ def latest(name,
remote_rev,
branch,
local_branch,
local_changes,
comments)
merge_action = 'hard-reset'
elif fast_forward is True:
@ -1153,11 +1180,10 @@ def latest(name,
remote_rev,
branch,
local_branch,
local_changes,
comments)
if _need_branch_change(branch, local_branch):
local_changes = __salt__['git.status'](target,
user=user)
if local_changes and not force_checkout:
return _fail(
ret,
@ -1199,6 +1225,9 @@ def latest(name,
'\'{0}\' was checked out'.format(checkout_rev)
)
if local_changes:
comments.append('Local changes were discarded')
if fast_forward is False:
__salt__['git.reset'](
target,

View file

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
'''
Send a message to Slack
=========================
=======================
This state is useful for sending messages to Slack during state runs.
@ -25,6 +25,12 @@ The api key can be specified in the master or minion configuration like below:
'''
# Import Python libs
from __future__ import absolute_import
# Import Salt libs
from salt.exceptions import SaltInvocationError
def __virtual__():
'''
@ -96,18 +102,18 @@ def post_message(name,
ret['comment'] = 'Slack message is missing: {0}'.format(message)
return ret
result = __salt__['slack.post_message'](
channel=channel,
message=message,
from_name=from_name,
api_key=api_key,
icon=icon,
)
if result:
try:
result = __salt__['slack.post_message'](
channel=channel,
message=message,
from_name=from_name,
api_key=api_key,
icon=icon,
)
except SaltInvocationError as sie:
ret['comment'] = 'Failed to send message: {0} ({1})'.format(name, sie)
else:
ret['result'] = True
ret['comment'] = 'Sent message: {0}'.format(name)
else:
ret['comment'] = 'Failed to send message: {0}'.format(name)
return ret

View file

@ -29,7 +29,7 @@ to use a YAML 'explicit key', as demonstrated in the second example below.
ssh_auth.present:
- user: root
- source: salt://ssh_keys/thatch.id_rsa.pub
- config: %h/.ssh/authorized_keys
- config: '%h/.ssh/authorized_keys'
sshkeys:
ssh_auth.present:

View file

@ -40,8 +40,6 @@ from salt.defaults import DEFAULT_TARGET_DELIM
from salt.utils.validate.path import is_writeable
from salt.utils.verify import verify_files
import salt.exceptions
# Import 3rd-party libs
import salt.ext.six as six
from salt.ext.six.moves import range # pylint: disable=import-error,redefined-builtin

View file

@ -54,11 +54,6 @@ except ImportError:
# Older jinja does not need markupsafe
HAS_MARKUPSAFE = False
try:
import xml
HAS_XML = True
except ImportError:
HAS_XML = False
# pylint: enable=import-error,no-name-in-module
try:
@ -129,10 +124,6 @@ def get_tops(extra_mods='', so_mods=''):
if HAS_SSL_MATCH_HOSTNAME:
tops.append(os.path.dirname(os.path.dirname(ssl_match_hostname.__file__)))
if HAS_XML:
# For openSUSE, which apparently doesn't include the whole stdlib
tops.append(os.path.dirname(xml.__file__))
for mod in [m for m in extra_mods.split(',') if m]:
if mod not in locals() and mod not in globals():
try:

View file

@ -1803,14 +1803,14 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
Execute salt
'''
arg_str = '-c {0} {1}'.format(self.get_config_dir(), arg_str)
return self.run_script('salt', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=timeout)
return self.run_script('salt', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
def run_ssh(self, arg_str, with_retcode=False, catch_stderr=False):
'''
Execute salt-ssh
'''
arg_str = '-W -c {0} -i --priv {1} --roster-file {2} --out=json localhost {3}'.format(self.get_config_dir(), os.path.join(TMP_CONF_DIR, 'key_test'), os.path.join(TMP_CONF_DIR, 'roster'), arg_str)
return self.run_script('salt-ssh', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, raw=True)
return self.run_script('salt-ssh', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, raw=True, timeout=30)
def run_run(self, arg_str, with_retcode=False, catch_stderr=False, async=False, timeout=60, config_dir=None):
'''
@ -1820,7 +1820,7 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
arg_str,
timeout=timeout,
async_flag=' --async' if async else '')
return self.run_script('salt-run', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr)
return self.run_script('salt-run', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
def run_run_plus(self, fun, options='', *arg, **kwargs):
'''
@ -1848,7 +1848,8 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
'salt-key',
arg_str,
catch_stderr=catch_stderr,
with_retcode=with_retcode
with_retcode=with_retcode,
timeout=30
)
def run_cp(self, arg_str, with_retcode=False, catch_stderr=False):
@ -1856,14 +1857,14 @@ class ShellCase(AdaptedConfigurationTestCaseMixIn, ShellTestCase, ScriptPathMixi
Execute salt-cp
'''
arg_str = '--config-dir {0} {1}'.format(self.get_config_dir(), arg_str)
return self.run_script('salt-cp', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr)
return self.run_script('salt-cp', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
def run_call(self, arg_str, with_retcode=False, catch_stderr=False):
'''
Execute salt-call.
'''
arg_str = '--config-dir {0} {1}'.format(self.get_config_dir(), arg_str)
return self.run_script('salt-call', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr)
return self.run_script('salt-call', arg_str, with_retcode=with_retcode, catch_stderr=catch_stderr, timeout=30)
def run_cloud(self, arg_str, catch_stderr=False, timeout=None):
'''

View file

@ -150,6 +150,53 @@ class GitTest(integration.ModuleCase, integration.SaltReturnAssertsMixIn):
finally:
shutil.rmtree(name, ignore_errors=True)
def test_latest_with_local_changes(self):
'''
Ensure that we fail the state when there are local changes and succeed
when force_reset is True.
'''
name = os.path.join(integration.TMP, 'salt_repo')
try:
# Clone repo
ret = self.run_state(
'git.latest',
name='https://{0}/saltstack/salt-test-repo.git'.format(self.__domain),
target=name
)
self.assertSaltTrueReturn(ret)
self.assertTrue(os.path.isdir(os.path.join(name, '.git')))
# Make change to LICENSE file.
with salt.utils.fopen(os.path.join(name, 'LICENSE'), 'a') as fp_:
fp_.write('Lorem ipsum dolor blah blah blah....\n')
# Make sure that we now have uncommitted changes
self.assertTrue(self.run_function('git.diff', [name, 'HEAD']))
# Re-run state with force_reset=False, this should fail
ret = self.run_state(
'git.latest',
name='https://{0}/saltstack/salt-test-repo.git'.format(self.__domain),
target=name,
force_reset=False
)
self.assertSaltFalseReturn(ret)
# Now run the state with force_reset=True, this should succeed
ret = self.run_state(
'git.latest',
name='https://{0}/saltstack/salt-test-repo.git'.format(self.__domain),
target=name,
force_reset=True
)
self.assertSaltTrueReturn(ret)
# Make sure that we no longer have uncommitted changes
self.assertFalse(self.run_function('git.diff', [name, 'HEAD']))
finally:
shutil.rmtree(name, ignore_errors=True)
def test_present(self):
'''
git.present

View file

@ -14,20 +14,8 @@ class KeyWheelModuleTest(integration.TestCase, integration.AdaptedConfigurationT
def test_list_all(self):
ret = self.wheel.call_func('key.list_all')
self.assertEqual({
'local': [
'master.pem',
'master.pub',
'minion.pem',
'minion.pub',
'minion_master.pub',
'syndic_master.pub'
],
'minions_rejected': [],
'minions_pre': [],
'minions_denied': [],
'minions': ['minion', 'sub_minion'],
}, ret)
for host in ['minion', 'sub_minion']:
self.assertIn(host, ret['minions'])
def test_gen(self):
ret = self.wheel.call_func('key.gen', id_='soundtechniciansrock')