Merge branch 'develop' into vagrant-module

This commit is contained in:
garethgreenaway 2017-10-10 08:27:16 -07:00 committed by GitHub
commit 4064bf4768
6 changed files with 84 additions and 26 deletions

View File

@ -10,6 +10,7 @@ The Azure cloud module is used to control access to Microsoft Azure
:depends: :depends:
* `Microsoft Azure SDK for Python <https://pypi.python.org/pypi/azure>`_ >= 2.0rc5 * `Microsoft Azure SDK for Python <https://pypi.python.org/pypi/azure>`_ >= 2.0rc5
* `Microsoft Azure Storage SDK for Python <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32 * `Microsoft Azure Storage SDK for Python <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32
* `Microsoft Azure CLI <https://pypi.python.org/pypi/azure-cli>` >= 2.0.12
:configuration: :configuration:
Required provider parameters: Required provider parameters:
@ -146,7 +147,13 @@ def __virtual__():
return False return False
if get_dependencies() is False: if get_dependencies() is False:
return False return (
False,
'The following dependencies are required to use the AzureARM driver: '
'Microsoft Azure SDK for Python >= 2.0rc5, '
'Microsoft Azure Storage SDK for Python >= 0.32, '
'Microsoft Azure CLI >= 2.0.12'
)
global cache # pylint: disable=global-statement,invalid-name global cache # pylint: disable=global-statement,invalid-name
cache = salt.cache.Cache(__opts__) cache = salt.cache.Cache(__opts__)

View File

@ -723,7 +723,7 @@ def create_node(vm_, newid):
newnode['hostname'] = vm_['name'] newnode['hostname'] = vm_['name']
newnode['ostemplate'] = vm_['image'] newnode['ostemplate'] = vm_['image']
static_props = ('cpuunits', 'description', 'memory', 'onboot', 'net0', static_props = ('cpuunits', 'cpulimit', 'rootfs', 'cores', 'description', 'memory', 'onboot', 'net0',
'password', 'nameserver', 'swap', 'storage', 'rootfs') 'password', 'nameserver', 'swap', 'storage', 'rootfs')
for prop in _get_properties('/nodes/{node}/lxc', for prop in _get_properties('/nodes/{node}/lxc',
'POST', 'POST',

View File

@ -128,12 +128,12 @@ def setup_handlers():
callable(transport_registry.compute_scope)): callable(transport_registry.compute_scope)):
conf_extras = transport_registry.compute_scope(url, dsn_config) conf_extras = transport_registry.compute_scope(url, dsn_config)
dsn_config.update(conf_extras) dsn_config.update(conf_extras)
options.update({ options.update({
'project': dsn_config['SENTRY_PROJECT'], 'project': dsn_config['SENTRY_PROJECT'],
'servers': dsn_config['SENTRY_SERVERS'], 'servers': dsn_config['SENTRY_SERVERS'],
'public_key': dsn_config['SENTRY_PUBLIC_KEY'], 'public_key': dsn_config['SENTRY_PUBLIC_KEY'],
'secret_key': dsn_config['SENTRY_SECRET_KEY'] 'secret_key': dsn_config['SENTRY_SECRET_KEY']
}) })
except ValueError as exc: except ValueError as exc:
log.info( log.info(
'Raven failed to parse the configuration provided ' 'Raven failed to parse the configuration provided '

View File

@ -9,6 +9,7 @@ import copy
import logging import logging
import os import os
import re import re
import stat
# Import salt libs # Import salt libs
import salt.utils import salt.utils
@ -118,6 +119,22 @@ def _expand_path(cwd, user):
return os.path.join(os.path.expanduser(to_expand), str(cwd)) return os.path.join(os.path.expanduser(to_expand), str(cwd))
def _path_is_executable_others(path):
'''
Check every part of path for executable permission
'''
prevpath = None
while path and path != prevpath:
try:
if not os.stat(path).st_mode & stat.S_IXOTH:
return False
except OSError:
return False
prevpath = path
path, _ = os.path.split(path)
return True
def _format_opts(opts): def _format_opts(opts):
''' '''
Common code to inspect opts and split them if necessary Common code to inspect opts and split them if necessary
@ -217,11 +234,12 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
} }
# copy wrapper to area accessible by ``runas`` user # copy wrapper to area accessible by ``runas`` user
# currently no suppport in windows for wrapping git ssh # currently no support in windows for wrapping git ssh
ssh_id_wrapper = os.path.join( ssh_id_wrapper = os.path.join(
salt.utils.templates.TEMPLATE_DIRNAME, salt.utils.templates.TEMPLATE_DIRNAME,
'git/ssh-id-wrapper' 'git/ssh-id-wrapper'
) )
tmp_ssh_wrapper = None
if salt.utils.platform.is_windows(): if salt.utils.platform.is_windows():
for suffix in ('', ' (x86)'): for suffix in ('', ' (x86)'):
ssh_exe = ( ssh_exe = (
@ -238,12 +256,14 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
# Use the windows batch file instead of the bourne shell script # Use the windows batch file instead of the bourne shell script
ssh_id_wrapper += '.bat' ssh_id_wrapper += '.bat'
env['GIT_SSH'] = ssh_id_wrapper env['GIT_SSH'] = ssh_id_wrapper
elif not user or _path_is_executable_others(ssh_id_wrapper):
env['GIT_SSH'] = ssh_id_wrapper
else: else:
tmp_file = salt.utils.files.mkstemp() tmp_ssh_wrapper = salt.utils.files.mkstemp()
salt.utils.files.copyfile(ssh_id_wrapper, tmp_file) salt.utils.files.copyfile(ssh_id_wrapper, tmp_ssh_wrapper)
os.chmod(tmp_file, 0o500) os.chmod(tmp_ssh_wrapper, 0o500)
os.chown(tmp_file, __salt__['file.user_to_uid'](user), -1) os.chown(tmp_ssh_wrapper, __salt__['file.user_to_uid'](user), -1)
env['GIT_SSH'] = tmp_file env['GIT_SSH'] = tmp_ssh_wrapper
if 'salt-call' not in _salt_cli \ if 'salt-call' not in _salt_cli \
and __salt__['ssh.key_is_encrypted'](id_file): and __salt__['ssh.key_is_encrypted'](id_file):
@ -273,13 +293,25 @@ def _git_run(command, cwd=None, user=None, password=None, identity=None,
redirect_stderr=redirect_stderr, redirect_stderr=redirect_stderr,
**kwargs) **kwargs)
finally: finally:
if not salt.utils.platform.is_windows() and 'GIT_SSH' in env: # Cleanup the temporary ssh wrapper file
os.remove(env['GIT_SSH']) try:
__salt__['file.remove'](tmp_ssh_wrapper)
log.debug('Removed ssh wrapper file %s', tmp_ssh_wrapper)
except AttributeError:
# No wrapper was used
pass
except (SaltInvocationError, CommandExecutionError) as exc:
log.warning('Failed to remove ssh wrapper file %s: %s', tmp_ssh_wrapper, exc)
# Cleanup the temporary identity file # Cleanup the temporary identity file
if tmp_identity_file and os.path.exists(tmp_identity_file): try:
log.debug('Removing identity file {0}'.format(tmp_identity_file))
__salt__['file.remove'](tmp_identity_file) __salt__['file.remove'](tmp_identity_file)
log.debug('Removed identity file %s', tmp_identity_file)
except AttributeError:
# No identify file was used
pass
except (SaltInvocationError, CommandExecutionError) as exc:
log.warning('Failed to remove identity file %s: %s', tmp_identity_file, exc)
# If the command was successful, no need to try additional IDs # If the command was successful, no need to try additional IDs
if result['retcode'] == 0: if result['retcode'] == 0:

View File

@ -363,7 +363,8 @@ def statelist(states_dict, sid_excludes=frozenset(['include', 'exclude'])):
REQUISITES = set([ REQUISITES = set([
'require', 'require_in', 'watch', 'watch_in', 'use', 'use_in', 'listen', 'listen_in' 'require', 'require_in', 'watch', 'watch_in', 'use', 'use_in', 'listen', 'listen_in',
'onchanges', 'onchanges_in', 'onfail', 'onfail_in'
]) ])
@ -405,8 +406,8 @@ def rename_state_ids(data, sls, is_extend=False):
del data[sid] del data[sid]
REQUIRE = set(['require', 'watch', 'listen']) REQUIRE = set(['require', 'watch', 'listen', 'onchanges', 'onfail'])
REQUIRE_IN = set(['require_in', 'watch_in', 'listen_in']) REQUIRE_IN = set(['require_in', 'watch_in', 'listen_in', 'onchanges_in', 'onfail_in'])
EXTENDED_REQUIRE = {} EXTENDED_REQUIRE = {}
EXTENDED_REQUIRE_IN = {} EXTENDED_REQUIRE_IN = {}
@ -414,8 +415,8 @@ from itertools import chain
# To avoid cycles among states when each state requires the one before it: # To avoid cycles among states when each state requires the one before it:
# explicit require/watch/listen can only contain states before it # explicit require/watch/listen/onchanges/onfail can only contain states before it
# explicit require_in/watch_in/listen_in can only contain states after it # explicit require_in/watch_in/listen_in/onchanges_in/onfail_in can only contain states after it
def add_implicit_requires(data): def add_implicit_requires(data):
def T(sid, state): # pylint: disable=C0103 def T(sid, state): # pylint: disable=C0103
@ -449,7 +450,7 @@ def add_implicit_requires(data):
for _, rstate, rsid in reqs: for _, rstate, rsid in reqs:
if T(rsid, rstate) in states_after: if T(rsid, rstate) in states_after:
raise SaltRenderError( raise SaltRenderError(
'State({0}) can\'t require/watch/listen a state({1}) defined ' 'State({0}) can\'t require/watch/listen/onchanges/onfail a state({1}) defined '
'after it!'.format(tag, T(rsid, rstate)) 'after it!'.format(tag, T(rsid, rstate))
) )
@ -459,7 +460,7 @@ def add_implicit_requires(data):
for _, rstate, rsid in reqs: for _, rstate, rsid in reqs:
if T(rsid, rstate) in states_before: if T(rsid, rstate) in states_before:
raise SaltRenderError( raise SaltRenderError(
'State({0}) can\'t require_in/watch_in/listen_in a state({1}) ' 'State({0}) can\'t require_in/watch_in/listen_in/onchanges_in/onfail_in a state({1}) '
'defined before it!'.format(tag, T(rsid, rstate)) 'defined before it!'.format(tag, T(rsid, rstate))
) )
@ -571,7 +572,7 @@ def extract_state_confs(data, is_extend=False):
if not is_extend and state_id in STATE_CONF_EXT: if not is_extend and state_id in STATE_CONF_EXT:
extend = STATE_CONF_EXT[state_id] extend = STATE_CONF_EXT[state_id]
for requisite in 'require', 'watch', 'listen': for requisite in 'require', 'watch', 'listen', 'onchanges', 'onfail':
if requisite in extend: if requisite in extend:
extend[requisite] += to_dict[state_id].get(requisite, []) extend[requisite] += to_dict[state_id].get(requisite, [])
to_dict[state_id].update(STATE_CONF_EXT[state_id]) to_dict[state_id].update(STATE_CONF_EXT[state_id])

View File

@ -259,6 +259,14 @@ def managed(name, ppa=None, **kwargs):
Use either ``keyid``/``keyserver`` or ``key_url``, but not both. Use either ``keyid``/``keyserver`` or ``key_url``, but not both.
key_text
The string representation of the GPG key to install.
.. note::
Use either ``keyid``/``keyserver``, ``key_url``, or ``key_text`` but
not more than one method.
consolidate : False consolidate : False
If set to ``True``, this will consolidate all sources definitions to the If set to ``True``, this will consolidate all sources definitions to the
sources.list file, cleanup the now unused files, consolidate components sources.list file, cleanup the now unused files, consolidate components
@ -312,6 +320,16 @@ def managed(name, ppa=None, **kwargs):
ret['result'] = False ret['result'] = False
ret['comment'] = 'You may not use both "keyid"/"keyserver" and ' \ ret['comment'] = 'You may not use both "keyid"/"keyserver" and ' \
'"key_url" argument.' '"key_url" argument.'
if 'key_text' in kwargs and ('keyid' in kwargs or 'keyserver' in kwargs):
ret['result'] = False
ret['comment'] = 'You may not use both "keyid"/"keyserver" and ' \
'"key_text" argument.'
if 'key_text' in kwargs and ('key_url' in kwargs):
ret['result'] = False
ret['comment'] = 'You may not use both "key_url" and ' \
'"key_text" argument.'
if 'repo' in kwargs: if 'repo' in kwargs:
ret['result'] = False ret['result'] = False
ret['comment'] = ('\'repo\' is not a supported argument for this ' ret['comment'] = ('\'repo\' is not a supported argument for this '