mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
Merge branch '2016.3' into '2016.11'
Conflicts: - salt/loader.py - salt/output/highstate.py - salt/runners/fileserver.py
This commit is contained in:
commit
f6aad99db2
@ -1463,7 +1463,10 @@ class LazyLoader(salt.utils.lazy.LazyDict):
|
||||
# It default's of course to the found callable attribute name
|
||||
# if no alias is defined.
|
||||
funcname = getattr(mod, '__func_alias__', {}).get(attr, attr)
|
||||
full_funcname = '{0}.{1}'.format(module_name, funcname)
|
||||
try:
|
||||
full_funcname = '.'.join((module_name, funcname))
|
||||
except TypeError:
|
||||
full_funcname = '{0}.{1}'.format(module_name, funcname)
|
||||
# Save many references for lookups
|
||||
# Careful not to overwrite existing (higher priority) functions
|
||||
if full_funcname not in self._dict:
|
||||
|
@ -4,6 +4,11 @@ Module for controlling Jenkins
|
||||
|
||||
.. versionadded:: 2016.3.0
|
||||
|
||||
:depends: python-jenkins_ Python module (not to be confused with jenkins_)
|
||||
|
||||
.. _python-jenkins: https://pypi.python.org/pypi/python-jenkins
|
||||
.. _jenkins: https://pypi.python.org/pypi/jenkins
|
||||
|
||||
:configuration: This module can be used by either passing an api key and version
|
||||
directly or by specifying both in a configuration profile in the salt
|
||||
master/minion config.
|
||||
@ -45,9 +50,15 @@ def __virtual__():
|
||||
:return: The virtual name of the module.
|
||||
'''
|
||||
if HAS_JENKINS:
|
||||
return __virtualname__
|
||||
if hasattr(jenkins, 'Jenkins'):
|
||||
return __virtualname__
|
||||
else:
|
||||
return (False,
|
||||
'The wrong Python module appears to be installed. Please '
|
||||
'make sure that \'python-jenkins\' is installed, not '
|
||||
'\'jenkins\'.')
|
||||
return (False, 'The jenkins execution module cannot be loaded: '
|
||||
'python jenkins library is not installed.')
|
||||
'python-jenkins is not installed.')
|
||||
|
||||
|
||||
def _connect():
|
||||
|
@ -2375,18 +2375,12 @@ def mod_repo(repo, basedir=None, **kwargs):
|
||||
)
|
||||
|
||||
# Build a list of keys to be deleted
|
||||
todelete = ['disabled']
|
||||
todelete = []
|
||||
for key in repo_opts:
|
||||
if repo_opts[key] != 0 and not repo_opts[key]:
|
||||
del repo_opts[key]
|
||||
todelete.append(key)
|
||||
|
||||
# convert disabled to enabled respectively from pkgrepo state
|
||||
if 'enabled' not in repo_opts:
|
||||
repo_opts['enabled'] = int(str(repo_opts.pop('disabled', False)).lower() != 'true')
|
||||
else:
|
||||
repo_opts.pop('disabled', False)
|
||||
|
||||
# Add baseurl or mirrorlist to the 'todelete' list if the other was
|
||||
# specified in the repo_opts
|
||||
if 'mirrorlist' in repo_opts:
|
||||
@ -2458,6 +2452,7 @@ def mod_repo(repo, basedir=None, **kwargs):
|
||||
if key in six.iterkeys(filerepos[repo].copy()):
|
||||
del filerepos[repo][key]
|
||||
|
||||
_bool_to_str = lambda x: '1' if x else '0'
|
||||
# Old file or new, write out the repos(s)
|
||||
filerepos[repo].update(repo_opts)
|
||||
content = header
|
||||
@ -2468,7 +2463,12 @@ def mod_repo(repo, basedir=None, **kwargs):
|
||||
del filerepos[stanza]['comments']
|
||||
content += '\n[{0}]'.format(stanza)
|
||||
for line in six.iterkeys(filerepos[stanza]):
|
||||
content += '\n{0}={1}'.format(line, filerepos[stanza][line])
|
||||
content += '\n{0}={1}'.format(
|
||||
line,
|
||||
filerepos[stanza][line]
|
||||
if not isinstance(filerepos[stanza][line], bool)
|
||||
else _bool_to_str(filerepos[stanza][line])
|
||||
)
|
||||
content += '\n{0}\n'.format(comments)
|
||||
|
||||
with salt.utils.fopen(repofile, 'w') as fileout:
|
||||
@ -2514,9 +2514,6 @@ def _parse_repo_file(filename):
|
||||
'Failed to parse line in %s, offending line was '
|
||||
'\'%s\'', filename, line.rstrip()
|
||||
)
|
||||
# YUM uses enabled field - create the disabled field so that comparisons works correctly in state
|
||||
if comps[0].strip() == 'enabled':
|
||||
repos[repo]['disabled'] = comps[1] != "1"
|
||||
|
||||
return (header, repos)
|
||||
|
||||
|
@ -172,7 +172,7 @@ def ext_pillar(minion_id,
|
||||
|
||||
pil = Pillar(opts, __grains__, minion_id, environment)
|
||||
|
||||
compiled_pillar = pil.compile_pillar()
|
||||
compiled_pillar = pil.compile_pillar(ext=False)
|
||||
|
||||
return compiled_pillar
|
||||
|
||||
|
@ -193,4 +193,4 @@ def ext_pillar(minion_id,
|
||||
opts = deepcopy(__opts__)
|
||||
opts['pillar_roots'][branch] = [pillar_dir]
|
||||
pil = Pillar(opts, __grains__, minion_id, branch)
|
||||
return pil.compile_pillar()
|
||||
return pil.compile_pillar(ext=False)
|
||||
|
@ -110,7 +110,7 @@ def managed(name, ppa=None, **kwargs):
|
||||
<salt.modules.yumpkg>`, :mod:`apt <salt.modules.aptpkg>`, and :mod:`zypper
|
||||
<salt.modules.zypper>` repositories are supported.
|
||||
|
||||
**YUM OR ZYPPER-BASED SYSTEMS**
|
||||
**YUM/DNF/ZYPPER-BASED SYSTEMS**
|
||||
|
||||
.. note::
|
||||
One of ``baseurl`` or ``mirrorlist`` below is required. Additionally,
|
||||
@ -124,6 +124,16 @@ def managed(name, ppa=None, **kwargs):
|
||||
repo. Secondly, it will be the name of the file as stored in
|
||||
/etc/yum.repos.d (e.g. ``/etc/yum.repos.d/foo.conf``).
|
||||
|
||||
enabled : True
|
||||
Whether or not the repo is enabled. Can be specified as True/False or
|
||||
1/0.
|
||||
|
||||
disabled : False
|
||||
Included to reduce confusion due to APT's use of the ``disabled``
|
||||
argument. If this is passed for a yum/dnf/zypper-based distro, then the
|
||||
reverse will be passed as ``enabled``. For example passing
|
||||
``disabled=True`` will assume ``enabled=False``.
|
||||
|
||||
humanname
|
||||
This is used as the "name" value in the repo file in
|
||||
``/etc/yum.repos.d/`` (or ``/etc/zypp/repos.d`` for SUSE distros).
|
||||
@ -201,10 +211,16 @@ def managed(name, ppa=None, **kwargs):
|
||||
'deb http://us.archive.ubuntu.com/ubuntu precise main':
|
||||
pkgrepo.managed
|
||||
|
||||
disabled
|
||||
disabled : False
|
||||
Toggles whether or not the repo is used for resolving dependencies
|
||||
and/or installing packages.
|
||||
|
||||
enabled : True
|
||||
Included to reduce confusion due to yum/dnf/zypper's use of the
|
||||
``enabled`` argument. If this is passed for an APT-based distro, then
|
||||
the reverse will be passed as ``disabled``. For example, passing
|
||||
``enabled=False`` will assume ``disabled=False``.
|
||||
|
||||
comps
|
||||
On apt-based systems, comps dictate the types of packages to be
|
||||
installed from the repository (e.g. main, nonfree, ...). For
|
||||
@ -279,14 +295,19 @@ def managed(name, ppa=None, **kwargs):
|
||||
'intended.')
|
||||
return ret
|
||||
|
||||
if 'enabled' in kwargs:
|
||||
salt.utils.warn_until(
|
||||
'Nitrogen',
|
||||
'The `enabled` argument has been deprecated in favor of '
|
||||
'`disabled`.'
|
||||
)
|
||||
enabled = kwargs.pop('enabled', None)
|
||||
disabled = kwargs.pop('disabled', None)
|
||||
|
||||
if enabled is not None and disabled is not None:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Only one of enabled/disabled is allowed'
|
||||
return ret
|
||||
elif enabled is None and disabled is None:
|
||||
# If neither argument was passed we assume the repo will be enabled
|
||||
enabled = True
|
||||
|
||||
repo = name
|
||||
os_family = __grains__['os_family'].lower()
|
||||
if __grains__['os'] in ('Ubuntu', 'Mint'):
|
||||
if ppa is not None:
|
||||
# overload the name/repo value for PPAs cleanly
|
||||
@ -296,26 +317,26 @@ def managed(name, ppa=None, **kwargs):
|
||||
except TypeError:
|
||||
repo = ':'.join(('ppa', str(ppa)))
|
||||
|
||||
elif __grains__['os_family'].lower() in ('redhat', 'suse'):
|
||||
kwargs['disabled'] = not salt.utils.is_true(enabled) \
|
||||
if enabled is not None \
|
||||
else salt.utils.is_true(disabled)
|
||||
|
||||
elif os_family in ('redhat', 'suse'):
|
||||
if 'humanname' in kwargs:
|
||||
kwargs['name'] = kwargs.pop('humanname')
|
||||
_val = lambda x: '1' if salt.utils.is_true(x) else '0'
|
||||
if 'disabled' in kwargs:
|
||||
if 'enabled' in kwargs:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Only one of enabled/disabled is permitted'
|
||||
return ret
|
||||
_reverse = lambda x: '1' if x == '0' else '0'
|
||||
kwargs['enabled'] = _reverse(_val(kwargs.pop('disabled')))
|
||||
elif 'enabled' in kwargs:
|
||||
kwargs['enabled'] = _val(kwargs['enabled'])
|
||||
if 'name' not in kwargs:
|
||||
# Fall back to the repo name if humanname not provided
|
||||
kwargs['name'] = repo
|
||||
|
||||
# Replace 'enabled' from kwargs with 'disabled'
|
||||
enabled = kwargs.pop('enabled', True)
|
||||
kwargs['disabled'] = not salt.utils.is_true(enabled)
|
||||
kwargs['enabled'] = not salt.utils.is_true(disabled) \
|
||||
if disabled is not None \
|
||||
else salt.utils.is_true(enabled)
|
||||
|
||||
elif os_family == 'nilinuxrt':
|
||||
# opkg is the pkg virtual
|
||||
kwargs['enabled'] = not salt.utils.is_true(disabled) \
|
||||
if disabled is not None \
|
||||
else salt.utils.is_true(enabled)
|
||||
|
||||
for kwarg in _STATE_INTERNAL_KEYWORDS:
|
||||
kwargs.pop(kwarg, None)
|
||||
@ -340,11 +361,10 @@ def managed(name, ppa=None, **kwargs):
|
||||
else:
|
||||
sanitizedkwargs = kwargs
|
||||
|
||||
if __grains__['os_family'] == 'Debian':
|
||||
if os_family == 'debian':
|
||||
repo = _strip_uri(repo)
|
||||
|
||||
if pre:
|
||||
needs_update = False
|
||||
for kwarg in sanitizedkwargs:
|
||||
if kwarg not in pre:
|
||||
if kwarg == 'enabled':
|
||||
@ -352,33 +372,40 @@ def managed(name, ppa=None, **kwargs):
|
||||
# not explicitly set, so we don't need to update the repo
|
||||
# if it's desired to be enabled and the 'enabled' key is
|
||||
# missing from the repo definition
|
||||
if __grains__['os_family'] == 'RedHat':
|
||||
if os_family == 'redhat':
|
||||
if not salt.utils.is_true(sanitizedkwargs[kwarg]):
|
||||
needs_update = True
|
||||
break
|
||||
else:
|
||||
needs_update = True
|
||||
break
|
||||
else:
|
||||
needs_update = True
|
||||
break
|
||||
elif kwarg == 'comps':
|
||||
if sorted(sanitizedkwargs[kwarg]) != sorted(pre[kwarg]):
|
||||
needs_update = True
|
||||
elif kwarg == 'line' and __grains__['os_family'] == 'Debian':
|
||||
break
|
||||
elif kwarg == 'line' and os_family == 'debian':
|
||||
# split the line and sort everything after the URL
|
||||
sanitizedsplit = sanitizedkwargs[kwarg].split()
|
||||
sanitizedsplit[3:] = sorted(sanitizedsplit[3:])
|
||||
reposplit = pre[kwarg].split()
|
||||
reposplit[3:] = sorted(reposplit[3:])
|
||||
if sanitizedsplit != reposplit:
|
||||
needs_update = True
|
||||
break
|
||||
if 'comments' in kwargs:
|
||||
_line = pre[kwarg].split('#')
|
||||
if str(kwargs['comments']) not in _line:
|
||||
needs_update = True
|
||||
break
|
||||
else:
|
||||
if str(sanitizedkwargs[kwarg]) != str(pre[kwarg]):
|
||||
needs_update = True
|
||||
|
||||
if not needs_update:
|
||||
if os_family in ('redhat', 'suse') \
|
||||
and any(isinstance(x, bool) for x in
|
||||
(sanitizedkwargs[kwarg], pre[kwarg])):
|
||||
# This check disambiguates 1/0 from True/False
|
||||
if salt.utils.is_true(sanitizedkwargs[kwarg]) != \
|
||||
salt.utils.is_true(pre[kwarg]):
|
||||
break
|
||||
else:
|
||||
if str(sanitizedkwargs[kwarg]) != str(pre[kwarg]):
|
||||
break
|
||||
else:
|
||||
ret['result'] = True
|
||||
ret['comment'] = ('Package repo \'{0}\' already configured'
|
||||
.format(name))
|
||||
@ -399,7 +426,7 @@ def managed(name, ppa=None, **kwargs):
|
||||
pass
|
||||
|
||||
try:
|
||||
if __grains__['os_family'] == 'Debian':
|
||||
if os_family == 'debian':
|
||||
__salt__['pkg.mod_repo'](repo, saltenv=__env__, **kwargs)
|
||||
else:
|
||||
__salt__['pkg.mod_repo'](repo, **kwargs)
|
||||
|
@ -87,7 +87,7 @@ def creds(provider):
|
||||
proxies={'http': ''}, timeout=AWS_METADATA_TIMEOUT,
|
||||
)
|
||||
result.raise_for_status()
|
||||
role = result.text.encode(result.encoding)
|
||||
role = result.text.encode(result.encoding or 'utf-8')
|
||||
except (requests.exceptions.HTTPError, requests.exceptions.ConnectionError):
|
||||
return provider['id'], provider['key'], ''
|
||||
|
||||
@ -460,7 +460,7 @@ def query(params=None, setname=None, requesturl=None, location=None,
|
||||
)
|
||||
LOG.trace(
|
||||
'AWS Response Text: {0}'.format(
|
||||
result.text.encode(result.encoding)
|
||||
result.text.encode(result.encoding or 'utf-8')
|
||||
)
|
||||
)
|
||||
result.raise_for_status()
|
||||
@ -501,7 +501,7 @@ def query(params=None, setname=None, requesturl=None, location=None,
|
||||
return {'error': data}, requesturl
|
||||
return {'error': data}
|
||||
|
||||
response = result.text.encode(result.encoding)
|
||||
response = result.text.encode(result.encoding or 'utf-8')
|
||||
|
||||
root = ET.fromstring(response)
|
||||
items = root[1]
|
||||
|
@ -7,6 +7,7 @@
|
||||
'''
|
||||
# Import python libs
|
||||
from __future__ import absolute_import, print_function
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import TestCase, skipIf
|
||||
@ -23,8 +24,10 @@ try:
|
||||
import jsonschema
|
||||
import jsonschema.exceptions
|
||||
HAS_JSONSCHEMA = True
|
||||
JSONSCHEMA_VERSION = _LooseVersion(jsonschema.__version__)
|
||||
except ImportError:
|
||||
HAS_JSONSCHEMA = False
|
||||
JSONSCHEMA_VERSION = _LooseVersion('0')
|
||||
|
||||
|
||||
class RoosterEntryConfigTest(TestCase):
|
||||
@ -296,7 +299,13 @@ class RosterItemTest(TestCase):
|
||||
ssh_schemas.RosterItem.serialize(),
|
||||
format_checker=jsonschema.FormatChecker()
|
||||
)
|
||||
self.assertIn(
|
||||
'Additional properties are not allowed (\'target-1:1\' was unexpected)',
|
||||
excinfo.exception.message
|
||||
)
|
||||
if JSONSCHEMA_VERSION < _LooseVersion('2.6.0'):
|
||||
self.assertIn(
|
||||
'Additional properties are not allowed (\'target-1:1\' was unexpected)',
|
||||
excinfo.exception.message
|
||||
)
|
||||
else:
|
||||
self.assertIn(
|
||||
'\'target-1:1\' does not match any of the regexes',
|
||||
excinfo.exception.message
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ import yaml
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
from distutils.version import LooseVersion
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# Import Salt Testing Libs
|
||||
from salttesting import TestCase, skipIf
|
||||
@ -27,10 +27,10 @@ try:
|
||||
import jsonschema
|
||||
import jsonschema.exceptions
|
||||
HAS_JSONSCHEMA = True
|
||||
JSONSCHEMA_VERSION = jsonschema.__version__
|
||||
JSONSCHEMA_VERSION = _LooseVersion(jsonschema.__version__)
|
||||
except ImportError:
|
||||
JSONSCHEMA_VERSION = ''
|
||||
HAS_JSONSCHEMA = False
|
||||
JSONSCHEMA_VERSION = _LooseVersion('0')
|
||||
|
||||
|
||||
# pylint: disable=unused-import
|
||||
@ -754,8 +754,7 @@ class ConfigTestCase(TestCase):
|
||||
}
|
||||
)
|
||||
|
||||
@skipIf(HAS_JSONSCHEMA is False, 'The \'jsonschema\' library is missing')
|
||||
@skipIf(HAS_JSONSCHEMA and LooseVersion(jsonschema.__version__) <= LooseVersion('2.5.0'), 'Requires jsonschema 2.5.0 or greater')
|
||||
@skipIf(JSONSCHEMA_VERSION <= _LooseVersion('2.5.0'), 'Requires jsonschema 2.5.0 or greater')
|
||||
def test_ipv4_config_validation(self):
|
||||
class TestConf(schema.Schema):
|
||||
item = schema.IPv4Item(title='Item', description='Item description')
|
||||
@ -1707,7 +1706,14 @@ class ConfigTestCase(TestCase):
|
||||
|
||||
with self.assertRaises(jsonschema.exceptions.ValidationError) as excinfo:
|
||||
jsonschema.validate({'item': {'color': 'green', 'sides': 4, 'surfaces': 4}}, TestConf.serialize())
|
||||
self.assertIn('Additional properties are not allowed', excinfo.exception.message)
|
||||
if JSONSCHEMA_VERSION < _LooseVersion('2.6.0'):
|
||||
self.assertIn(
|
||||
'Additional properties are not allowed',
|
||||
excinfo.exception.message)
|
||||
else:
|
||||
self.assertIn(
|
||||
'\'surfaces\' does not match any of the regexes',
|
||||
excinfo.exception.message)
|
||||
|
||||
class TestConf(schema.Schema):
|
||||
item = schema.DictItem(
|
||||
|
Loading…
Reference in New Issue
Block a user